Win32 RPC 编程(一) 示例下载
1.首先使用uuidgen工具($(VS)\Common7\Tools)生成idl接口文件
uuidgen /i /ohello.idl
注意"/o"和文件名之间没有空白!
2.然后打开生成的接口文件,在里面添加接口
Cpp代码
- [
- uuid(d1717d33-8e03-456c-a79b-57fc212f5042),
- version(1.0),
- pointer_default(unique)
- ]
- interface hello
- {
- void HelloProc([in, string] unsigned char * pszString);
- void ShutDown(void);
- }
3.编写acf文件,此文件要与idl文件同名且放在同一目录下。此文件是可选的。
Cpp代码
- [
- implicit_handle (handle_t hello_Binding)
- ]
- interface hello
- {
- }
4.使用midl编译idl文件
midl hello.idl
编译生成hello.h, hello_c.c, hello_s.c三个文件。hello.h为客户端和服务端共用头文件,hello_c.c要放到客户端,hello_s.c要放到服务端。
5.服务端部分代码
Cpp代码
- #include <iostream>
- #include <hello.h>
- using namespace std;
- int main(void)
- {
- RPC_STATUS status = 0;
- unsigned int nMinCalls = 1;
- unsigned int nMaxCalls = 20;
- status = RpcServerUseProtseqEp(
- (unsigned char *)"ncacn_np",
- nMaxCalls,
- (unsigned char *)"\\pipe\\{a5194558-21a6-4978-9610-2072fcf1dc6e}",
- NULL );
- if ( status != 0 )
- {
- cout<<"RpcServerUseProtseqEp return "<<status<<" !"<<endl;
- return 1;
- }
- status = RpcServerRegisterIf(
- hello_v1_0_s_ifspec,
- NULL,
- NULL );
- if ( status != 0 )
- {
- cout<<"RpcServerRegisterIf return "<<status<<" !"<<endl;
- return 1;
- }
- cout<<"Begin RPC server listen!"<<endl;
- status = RpcServerListen(
- nMinCalls,
- nMaxCalls,
- FALSE );
- if ( status != 0 )
- {
- cout<<"RpcServerListen return "<<status<<" !"<<endl;
- return 1;
- }
- cin.get();
- return 0;
- }
- void * __RPC_USER MIDL_user_allocate(size_t len)
- {
- return (malloc(len));
- }
- void __RPC_USER MIDL_user_free(void* ptr)
- {
- free(ptr);
- }
- void HelloProc(unsigned char *pszString)
- {
- cout<<pszString<<endl;
- }
- void ShutDown()
- {
- RPC_STATUS status = 0;
- status = RpcMgmtStopServerListening(NULL);
- if ( status != 0 )
- cout<<"RpcMgmtStopServerListening return "<<status<<" !"<<endl;
- status = RpcServerUnregisterIf(NULL, NULL, FALSE);
- if ( status != 0 )
- cout<<"RpcServerUnregisterIf return "<<status<<" !"<<endl;
- }
6.客户端代码
Cpp代码
- #include <iostream>
- #include <string>
- #include <hello.h>
- using namespace std;
- void doRpcCall();
- int main(int argc, char** argv)
- {
- RPC_STATUS status;
- unsigned char * pszNetworkAddress = NULL;
- unsigned char * pszStringBinding = NULL;
- for ( int i = 1; i < argc; ++i )
- {
- if ( strcmp(argv[i], "-ip") == 0 )
- {
- pszNetworkAddress = (unsigned char *)argv[++i];
- }
- }
- status = RpcStringBindingCompose(
- NULL,
- (unsigned char *)"ncacn_np",
- pszNetworkAddress,
- (unsigned char *)"\\pipe\\{a5194558-21a6-4978-9610-2072fcf1dc6e}",
- NULL,
- &pszStringBinding );
- if ( status != 0 )
- {
- cout<<"RpcStringBindingCompose return "<<status<<" !"<<endl;
- return 1;
- }
- cout<<"pszStringBinding = "<<pszStringBinding<<endl;
- status = RpcBindingFromStringBinding(
- pszStringBinding,
- &hello_Binding );
- if ( status != 0 )
- {
- cout<<"RpcBindingFromStringBinding return "<<status<<" !"<<endl;
- return 1;
- }
- doRpcCall();
- status = RpcStringFree( &pszStringBinding );
- if ( status != 0 )
- cout<<"RpcStringFree return "<<status<<" !"<<endl;
- status = RpcBindingFree( &hello_Binding );
- if ( status != 0 )
- cout<<"RpcBindingFree return "<<status<<" !"<<endl;
- cin.get();
- return 0;
- }
- void doRpcCall()
- {
- char buff[1024];
- RpcTryExcept
- {
- while (true)
- {
- cout<<"Please input a string param for RPC call:"<<endl;
- cin.getline(buff, 1023);
- if ( strcmp(buff, "exit") == 0 || strcmp(buff, "quit") == 0 )
- {
- ShutDown();
- break;
- }
- else
- {
- HelloProc( (unsigned char *)buff );
- cout<<"RPC call <HelloProc> succeed!"<<endl;
- }
- }
- }
- RpcExcept(1)
- {
- unsigned long ulCode = RpcExceptionCode();
- cout<<"RPC exception occured! code: "<<ulCode<<endl;
- }
- RpcEndExcept
- }
- void * __RPC_USER MIDL_user_allocate(size_t len)
- {
- return (malloc(len));
- }
- void __RPC_USER MIDL_user_free(void* ptr)
- {
- free(ptr);
- }