Windows C++ 使用WinAPI实现RPC

demo下载地址:https://download.csdn.net/download/2403_83063732/88958730
1、创建IDL文件以及acf文件(创建helloworld.idl helloworld.acf)

其中IDL文件:

import "oaidl.idl";

import "ocidl.idl";

uuid("4556509F-618A-46CF-AB3D-ED736ED66477"), // 唯一的UUID,主要是用来通讯的时候使用 version(1.0)

interface HelloWorld

{

// 官方文档推荐的自定义字符串写法(带长度和大小)

typedef struct _MYSTRING

{

unsigned short size;

unsigned short length;

ptr,size_is(size), length_is(length)\] char string\[\*\]; } MYSTRING; typedef \[ptr\] MYSTRING\*\* PPMYSTRING; typedef \[ptr\] MYSTRING\* PMYSTRING; // 我们定义的方法,只列举这几个应该够我们用了 void Hello(\[in, string\]const char \* psz);//只输入,不带返回值 int Add(\[in\]int a1,\[in\]int a2);//带返回值 int GetTestString(\[out\]PMYSTRING \*pName);//可以获取对端的数据,比如状态或者其他 }

implicit_handle (handle_t HelloWorld_IfHandle)

interface HelloWorld

{

}

2、调用midl指令,生成.c/.h文件

midl helloworld.idl /acf helloworld.acf /out ./

如下生成helloworld.h ,helloworld_c.h,helloworld_s.h

3、创建客户端工程以及服务端工程

客户端工程包含helloworld.h ,helloworld_c.h

服务端工程包含helloworld.h ,helloworld_s.h

如下图

4、服务端代码

midl_user_allocate/midl_user_free函数必须要,不然编译会报错

#include "../TestRpcC/helloworld.h"

#pragma comment(lib,"Rpcrt4.lib")

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);

}

void Hello( const unsigned char * psz)

{

printf("Hello:%s\n", psz);

}

int Add(

/* [in] */ int a1,

/* [in] */ int a2)

{

return a1 + a2;

}

int GetTestString(

/* [out] */ PMYSTRING *pName)

{

int nLen = strlen("test");

*pName = (PMYSTRING)MIDL_user_allocate(sizeof(PMYSTRING) + nLen);

(*pName)->length = nLen;

(*pName)->size = sizeof(PMYSTRING) + nLen;

strncpy((char*)(*pName)->string, "test", nLen);

return nLen;

}

int main()

{

// 用Named Pipe 作为RPC 的通道,这样EndPoint 参数就是Named Pipe 的名字

// 按照Named Pipe 的命名规范,/pipe/pipename,其中pipename 可以是除了/

// 之外的任意字符,那么这里用一个GUID 串来命名,可以保证不会重复

RPC_STATUS st = RpcServerUseProtseqEpA((unsigned char *)"ncacn_np", 20, (unsigned char *)"\\pipe\\{8dd50205-3108-498f-96e8-dbc4ec074cf9}", NULL);

if (st != RPC_S_OK)

{

return -1;

}

// 注册接口,HelloWorld_v1_0_s_ifspec 是在MIDL 生成的helloworld.h 中定义的

st = RpcServerRegisterIf(HelloWorld_v1_0_s_ifspec, NULL, NULL);

if (st != RPC_S_OK)

{

return -1;

}

// 开始监听,本函数将一直阻塞

st = RpcServerListen(1, 20, FALSE);

if (st != RPC_S_OK)

{

return -1;

}

return 0;

}

5、客户端代码

midl_user_allocate/midl_user_free函数必须要,不然编译会报错

#include "helloworld.h"

#pragma comment(lib,"Rpcrt4.lib")

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()

{

unsigned char *pszUuid = NULL;

unsigned char pszProtocolSequence[] = "ncacn_np";

unsigned char *pszNetworkAddress = NULL;

unsigned char pszEndpoint[] = "\\pipe\\{8dd50205-3108-498f-96e8-dbc4ec074cf9}";

unsigned char *pszOptions = NULL;

unsigned char *pszStringBinding = NULL;

RPC_STATUS rpcStatus = RpcStringBindingComposeA(pszUuid,

pszProtocolSequence,

pszNetworkAddress,

pszEndpoint,

pszOptions,&pszStringBinding);

if (rpcStatus)

exit(rpcStatus);

rpcStatus = RpcBindingFromStringBindingA(pszStringBinding,&HelloWorld_IfHandle);

if (rpcStatus)

exit(rpcStatus);

RpcTryExcept

{

Hello((unsigned char *)"nihaosadjklasjldkjaskldjkasdasdasdasdasdasdasdasd");

int ret = Add(16, 40);

printf("ret = %d \n", ret);

PMYSTRING baseData = NULL;

ret = GetTestString(&baseData);

if (ret > 0)

{

char *pBuf = new char[ret + 1];

memset(pBuf,0,ret + 1);

memcpy(pBuf, baseData->string,ret);

printf("ret = {%d,%s} \n", ret, pBuf);

delete[]pBuf;

}

}

RpcExcept(1)

{

unsigned long ulCode = RpcExceptionCode();

printf("抛出异常0x%lx = %ld。\n", ulCode, ulCode);

}

RpcEndExcept

rpcStatus = RpcStringFreeA(&pszStringBinding);

if (rpcStatus)

exit(rpcStatus);

rpcStatus = RpcBindingFree(&HelloWorld_IfHandle);

if (rpcStatus)

exit(rpcStatus);

return 0;

}

6、运行结果
相关推荐
玉树临风ives5 分钟前
atcoder ABC436 题解
c++·算法·leetcode·atcoder·信息学奥赛
fpcc6 分钟前
C++23中的自定义模块开发
c++·c++23
总有刁民想爱朕ha19 分钟前
Windows Server 2019部署PostgreSQL 14教程
数据库·windows·postgresql
qq_3106585138 分钟前
mediasoup源码走读(十二)——router
服务器·c++·音视频
落羽的落羽1 小时前
【C++】哈希扩展——位图和布隆过滤器的介绍与实现
linux·服务器·开发语言·c++·人工智能·算法·机器学习
汪宁宇1 小时前
如何在QT5+MinGW环境中编译使用QGIS开发地图应用
c++·qt·qgis·mingw·地图库
fish_xk1 小时前
类和对象(二)
开发语言·c++·算法
MC皮蛋侠客1 小时前
C++编译死机排查工具与实战指南
c++
tang&1 小时前
双指针算法:化繁为简的优雅解法
数据结构·c++·算法
爱装代码的小瓶子1 小时前
【c++知识铺子】封装map和set(详细版)
android·java·c++