Win32 RPC 编程(一)  示例下载


1.首先使用uuidgen工具($(VS)\Common7\Tools)生成idl接口文件

uuidgen /i /ohello.idl

注意"/o"和文件名之间没有空白!

2.然后打开生成的接口文件,在里面添加接口

 Cpp代码

  1. [   
  2.     uuid(d1717d33-8e03-456c-a79b-57fc212f5042),   
  3.     version(1.0),   
  4.     pointer_default(unique)   
  5. ]   
  6.   
  7. interface hello   
  8. {   
  9.     void HelloProc([in, string] unsigned char * pszString);   
  10.     void ShutDown(void);   
  11. }  

 3.编写acf文件,此文件要与idl文件同名且放在同一目录下。此文件是可选的。

 Cpp代码

  1. [   
  2.     implicit_handle (handle_t hello_Binding)   
  3. ]   
  4.   
  5. interface hello   
  6. {   
  7. }  

4.使用midl编译idl文件

midl hello.idl

编译生成hello.h, hello_c.c, hello_s.c三个文件。hello.h为客户端和服务端共用头文件,hello_c.c要放到客户端,hello_s.c要放到服务端。

5.服务端部分代码

 Cpp代码

  1. #include <iostream>   
  2. #include <hello.h>   
  3.   
  4. using namespace std;   
  5.   
  6. int main(void)   
  7. {   
  8.     RPC_STATUS status = 0;   
  9.   
  10.     unsigned int nMinCalls = 1;   
  11.     unsigned int nMaxCalls = 20;   
  12.   
  13.     status = RpcServerUseProtseqEp(   
  14.         (unsigned char *)"ncacn_np",   
  15.         nMaxCalls,   
  16.         (unsigned char *)"\\pipe\\{a5194558-21a6-4978-9610-2072fcf1dc6e}",   
  17.         NULL );   
  18.     if ( status != 0 )   
  19.     {   
  20.         cout<<"RpcServerUseProtseqEp return "<<status<<" !"<<endl;   
  21.         return 1;   
  22.     }   
  23.   
  24.     status = RpcServerRegisterIf(   
  25.         hello_v1_0_s_ifspec,   
  26.         NULL,   
  27.         NULL );   
  28.     if ( status != 0 )   
  29.     {   
  30.         cout<<"RpcServerRegisterIf return "<<status<<" !"<<endl;   
  31.         return 1;   
  32.     }   
  33.   
  34.     cout<<"Begin RPC server listen!"<<endl;   
  35.   
  36.     status = RpcServerListen(   
  37.         nMinCalls,   
  38.         nMaxCalls,   
  39.         FALSE );   
  40.     if ( status != 0 )   
  41.     {   
  42.         cout<<"RpcServerListen return "<<status<<" !"<<endl;   
  43.         return 1;   
  44.     }   
  45.   
  46.     cin.get();   
  47.     return 0;   
  48. }   
  49.   
  50. void * __RPC_USER MIDL_user_allocate(size_t len)   
  51. {   
  52.     return (malloc(len));   
  53. }   
  54.   
  55. void __RPC_USER MIDL_user_free(void* ptr)   
  56. {   
  57.     free(ptr);   
  58. }   
  59.   
  60. void HelloProc(unsigned char *pszString)   
  61. {   
  62.     cout<<pszString<<endl;   
  63. }   
  64.   
  65. void ShutDown()   
  66. {   
  67.     RPC_STATUS status = 0;   
  68.   
  69.     status = RpcMgmtStopServerListening(NULL);   
  70.     if ( status != 0 )   
  71.         cout<<"RpcMgmtStopServerListening return "<<status<<" !"<<endl;   
  72.   
  73.     status = RpcServerUnregisterIf(NULL, NULL, FALSE);   
  74.     if ( status != 0 )   
  75.         cout<<"RpcServerUnregisterIf return "<<status<<" !"<<endl;   
  76. }  

 6.客户端代码

 Cpp代码

  1. #include <iostream>   
  2. #include <string>   
  3. #include <hello.h>   
  4.   
  5. using namespace std;   
  6.   
  7. void doRpcCall();   
  8.   
  9. int main(int argc, char** argv)   
  10. {   
  11.     RPC_STATUS status;   
  12.   
  13.     unsigned char * pszNetworkAddress = NULL;   
  14.     unsigned char * pszStringBinding = NULL;   
  15.   
  16.     for ( int i = 1; i < argc; ++i )   
  17.     {   
  18.         if ( strcmp(argv[i], "-ip") == 0 )   
  19.         {   
  20.             pszNetworkAddress = (unsigned char *)argv[++i];   
  21.         }   
  22.     }   
  23.   
  24.     status = RpcStringBindingCompose(   
  25.         NULL,   
  26.         (unsigned char *)"ncacn_np",   
  27.         pszNetworkAddress,   
  28.         (unsigned char *)"\\pipe\\{a5194558-21a6-4978-9610-2072fcf1dc6e}",   
  29.         NULL,   
  30.         &pszStringBinding );   
  31.     if ( status != 0 )   
  32.     {   
  33.         cout<<"RpcStringBindingCompose return "<<status<<" !"<<endl;   
  34.         return 1;   
  35.     }   
  36.   
  37.     cout<<"pszStringBinding = "<<pszStringBinding<<endl;   
  38.   
  39.     status = RpcBindingFromStringBinding(   
  40.         pszStringBinding,   
  41.         &hello_Binding );   
  42.     if ( status != 0 )   
  43.     {   
  44.         cout<<"RpcBindingFromStringBinding return "<<status<<" !"<<endl;   
  45.         return 1;   
  46.     }   
  47.   
  48.     doRpcCall();   
  49.   
  50.     status = RpcStringFree( &pszStringBinding );   
  51.     if ( status != 0 )   
  52.         cout<<"RpcStringFree return "<<status<<" !"<<endl;   
  53.   
  54.     status = RpcBindingFree( &hello_Binding );   
  55.     if ( status != 0 )   
  56.         cout<<"RpcBindingFree return "<<status<<" !"<<endl;   
  57.   
  58.     cin.get();   
  59.     return 0;   
  60. }   
  61.   
  62. void doRpcCall()   
  63. {   
  64.     char buff[1024];   
  65.   
  66.     RpcTryExcept   
  67.     {   
  68.         while (true)   
  69.         {   
  70.             cout<<"Please input a string param for RPC call:"<<endl;   
  71.             cin.getline(buff, 1023);   
  72.   
  73.             if ( strcmp(buff, "exit") == 0 || strcmp(buff, "quit") == 0 )   
  74.             {   
  75.                 ShutDown();   
  76.                 break;   
  77.             }   
  78.             else  
  79.             {   
  80.                 HelloProc( (unsigned char *)buff );   
  81.                 cout<<"RPC call <HelloProc> succeed!"<<endl;   
  82.             }   
  83.         }     
  84.     }   
  85.     RpcExcept(1)   
  86.     {   
  87.         unsigned long ulCode = RpcExceptionCode();   
  88.         cout<<"RPC exception occured! code: "<<ulCode<<endl;   
  89.     }   
  90.     RpcEndExcept   
  91. }   
  92.   
  93. void * __RPC_USER MIDL_user_allocate(size_t len)   
  94. {   
  95.     return (malloc(len));   
  96. }   
  97.   
  98. void __RPC_USER MIDL_user_free(void* ptr)   
  99. {   
  100.     free(ptr);   
  101. }