Windows RPC编程入门

Home / Hackintosh MrLee 2016-4-20 4388

Windows本身支持成为一个RPC服务器。MSDN里面有个很好的例子,但是,WindowsXP上面默认的RPC/tcpip功能没有打开,必须运行gpedit.msc,计算机配置->管理模版->系统->远程过程调用->用于未验证的RPC...->选择"已启动",限定项选择"无"。用VC2010express建立两个工程,按照MSDN的例子: 首先,idl文件my.idl:
[
  uuid(ba209999-0c6c-11d2-97cf-00c04f8eea45),
  version(1.0)
]
interface hw // The interface is named hw
{
   // A function that takes a zero-terminated string.
   void Hello(
      [in, string] const char* szOutput);
}

编译以后,相应的文件放到服务器端和客户端程序里面去。 服务器端实现:
#include"stdafx.h"
#include
#include
#include"my_h.h"
#pragma comment(lib,"rpcrt4")
#pragma comment(lib,"ole32")
extern "C"{
void Hello(handle_t IDL_handle,const unsigned char*psz){
    printf("server:%s\n",psz);
}
void Shutdown(handle_t IDL_handle){
    RpcMgmtStopServerListening(NULL);
    RpcServerUnregisterIf(NULL,NULL,FALSE);
}
void* /*__RPC_FAR**/ __RPC_USER midl_user_allocate(size_t len){
    return(malloc(len));
}
void __RPC_USER midl_user_free(void __RPC_FAR* ptr){
    free(ptr);
}
}
int main()
{
   RPC_STATUS status;
   status = RpcServerUseProtseqEp(
      (RPC_CSTR)("ncacn_ip_tcp"), // Use TCP/IP protocol.
      RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // Backlog queue length for TCP/IP.
      (RPC_CSTR)("4747"), // TCP/IP port to use.
      NULL); // No security.
   if (status){
       printf("ServerUse failed\n");
       exit(status);}
   else printf("UseProtseqEq ok\n");
   status = RpcServerRegisterIf(
      hw_v1_0_s_ifspec, // Interface to register.
      NULL, // Use the MIDL generated entry-point vector.
      NULL);// Use the MIDL generated entry-point vector.
   if (status){
       printf("Register failed\n");
       exit(status);}
   else printf("Register if ok\n");
   // This call will not return until
   // RpcMgmtStopServerListening is called.
   status = RpcServerListen(
     1, // Recommended minimum number of threads.
     RPC_C_LISTEN_MAX_CALLS_DEFAULT, // Recommended maximum number of threads.
     FALSE); // Start listening now.
   if (status){
       printf("Server listen failed\n");
       exit(status);}
   else printf("listen ok\n");
   return 0;
}

启动以后显示: UseProtseqEq ok Register if ok 客户端代码:
// myclient.cpp : Defines the entry point for the console application.
#include"stdafx.h"
#include
#include
#include"my_h.h"
#pragma comment(lib,"rpcrt4")
#pragma comment(lib,"ole32")
int main(void){
    RPC_STATUS status;
    RPC_BINDING_HANDLE hwBinding;
    unsigned char* szStringBinding=NULL;
    status=RpcStringBindingCompose(//建立一个String Binding句柄,并不连接
        NULL,
        (RPC_CSTR)("ncacn_ip_tcp"),
        (RPC_CSTR)("localhost"),
        (RPC_CSTR)("4747"),
        NULL,
        (RPC_CSTR*)&szStringBinding);
    if(status){
        printf("StringBinding failed\n");
        exit(status);}
    printf("szString=%s\n",szStringBinding);
    status=RpcBindingFromStringBinding(
        szStringBinding,
        &hwBinding);
    if(status){
        printf("Bind from String failed:%d\n",GetLastError());
        exit(status);}
    RpcTryExcept{
                Hello(hwBinding,(RPC_CSTR)("Hello RPC World!"));
   }
   RpcExcept(1){
      printf("Runtime reported exception:%d,except=%d\n",GetLastError(),RpcExceptionCode()/*RPC_S_ACCESS_DENIED==5L*/);//这里返回了5
   }
   RpcEndExcept
   status = RpcBindingFree(&hwBinding); // Frees the binding handle.
   if (status){
       printf("Bind free failed\n");
       exit(status);}
    return 0;
}
void* __RPC_USER midl_user_allocate(size_t size){
    return malloc(size);
}
// Memory deallocation function for RPC.
void __RPC_USER midl_user_free(void* p){
    free(p);
}

运行显示: szString=ncacn_ip_tcp:localhost[4747]
此时,服务器端显示: server:Hello RPC World! 多次启动客户端,上面这句话显示多次。

本文链接:https://www.it72.com/9277.htm

推荐阅读
最新回复 (0)
返回