音乐网站的设计与开发,长沙网络公关公司,亚马逊雨林简介,有品质的网站推广公司概述#xff1a;windows 创建 RPC调用过程实例详解 参考文章#xff1a;Remote procedure call (RPC)#xff08;远程过程调用 (RPC)#xff09; - Win32 apps | Microsoft Learn 文章目录 0x01、生成 UUID 和模版(IDL)文件0x02、添加 acf 文件0x03、编译 idl 文件0x04、客… 概述windows 创建 RPC调用过程实例详解 参考文章Remote procedure call (RPC)远程过程调用 (RPC) - Win32 apps | Microsoft Learn 文章目录 0x01、生成 UUID 和模版(IDL)文件0x02、添加 acf 文件0x03、编译 idl 文件0x04、客户端main.cpp 0x05、服务端main.cpp 0x06、编译并运行0x07、运行示例ClientServer 0x01、生成 UUID 和模版(IDL)文件
定义接口的第一步是使用 uuidgen 实用工具生成通用唯一标识符UUID。UUID使客户端和服务端能够相互识别。该工具包含在阿庄平台软件开发工具包中SDK。
一般安装路径位于D:\Windows Kits\10\bin\10.0.22621.0\x64
以下命令生成 UUID 并创建名为 Hello.idl 的模版文件。
uuidgen /i /ohello.idl模版内容大致如下
[uuid(7a98c250-6808-11cf-b73b-00aa00b677a7),version(1.0)
]
interface hello
{}在模版中添加接口
//file hello.idl
[uuid(7a98c250-6808-11cf-b73b-00aa00b677a7),version(1.0)
]
interface hello
{void HelloProc([in, string] unsigned char * pszString);void Shutdown(void);
}0x02、添加 acf 文件
acf文件内容如下所示导出接口需要与 idl 文件一致
//file: hello.acf
[implicit_handle (handle_t hello_IfHandle)
]
interface hello
{
}0x03、编译 idl 文件 打开 visual studio新建一个空项目 空项目中添加上述 idl文件 和 acf文件 编译项目 生成 hello_h.h、hello_c.c、hello_s.c hello_h.h: 服务端和客户端共用文件hello_c.c: 客户端文件hello_s.c: 服务端文件 需要补充说明的是在 hello_h.h 头文件中有两个导出接口导出接口即为rpc调用的接口。 extern RPC_IF_HANDLE hello_v1_0_c_ifspec;
extern RPC_IF_HANDLE hello_v1_0_s_ifspec;0x04、客户端
新建工程文件如下所示
main.cpp
//client.cpp
#include iostream
#include string
using namespace std;#include hello_h.h#pragma comment(lib,Rpcrt4.lib)void doRpcCall();int main(int argc, char** argv)
{int i 0;RPC_STATUS status 0;unsigned char* pszNetworkAddr NULL;unsigned char* pszStringBinding NULL;for (i 1; i argc; i) {if (strcmp(argv[i], -ip) 0) {pszNetworkAddr (unsigned char*)argv[i];break;}}status RpcStringBindingCompose(NULL,(unsigned char*)ncacn_np,pszNetworkAddr,(unsigned char*)\\pipe\\hello,NULL,pszStringBinding);if (status ! 0) {cout RpcStringBindingCompose returns: status ! endl;return -1;}cout pszStringBinding pszStringBinding endl;status RpcBindingFromStringBinding(pszStringBinding, hello_IfHandle);if (status ! 0) {cout RpcBindingFromStringBinding returns: status ! endl;return -1;}doRpcCall();status RpcStringFree(pszStringBinding);if (status ! 0)cout RpcStringFree returns: status ! endl;status RpcBindingFree(hello_IfHandle);if (status ! 0)cout RpcBindingFree returns: status ! endl;cin.get();return 0;
}void doRpcCall(void)
{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();}else {HelloProc((unsigned char*)buff);cout 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);
}0x05、服务端
新建工程文件如下所示
main.cpp
#include iostream
using namespace std;#include hello_h.h#pragma comment(lib,Rpcrt4.lib)int main(void)
{RPC_STATUS status 0;unsigned int mincall 1;unsigned int maxcall 20;status RpcServerUseProtseqEp((unsigned char*)ncacn_np,maxcall,(unsigned char*)\\pipe\\hello,NULL);if (status ! 0) {cout RpcServerUseProtseqEp returns: status endl;return -1;}status RpcServerRegisterIf(hello_v1_0_s_ifspec,NULL,NULL);if (status ! 0) {cout RpcServerRegisterIf returns: status endl;return -1;}cout Rpc Server Begin Listening... endl;status RpcServerListen(mincall, maxcall, FALSE);if (status ! 0) {cout RpcServerListen returns: status endl;return -1;}cin.get();return 0;
}/************************************************************************/
/* MIDL malloc free */
/************************************************************************/void* __RPC_USER MIDL_user_allocate(size_t len)
{return (malloc(len));
}void __RPC_USER MIDL_user_free(void* ptr)
{free(ptr);
}/************************************************************************/
/* Interfaces */
/************************************************************************/void HelloProc(unsigned char* szhello)
{cout szhello endl;
}void Shutdown(void)
{RPC_STATUS status 0;status RpcMgmtStopServerListening(NULL);if (status ! 0) {cout RpcMgmtStopServerListening returns: status ! endl;}status RpcServerUnregisterIf(NULL, NULL, FALSE);if (status ! 0) {cout RpcServerUnregisterIf returns: status ! endl;}
}0x06、编译并运行
分别编译客户端和服务端程序得到 server.exe 和 client.exe
先运行 server.exe在 client.exe 目录运行 client -ip 192.168.106.128 来启动客户端程序并与服务器端相连在 client 的窗口输入任意字符串回车后可看到server窗口上有显示在 client 窗口内 输入 exit 或 quit, server 窗口关闭
0x07、运行示例
Client Server