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, stringconst char * psz);//只输入,不带返回值

int Add(inint a1,inint a2);//带返回值

int GetTestString(outPMYSTRING *pName);//可以获取对端的数据,比如状态或者其他

}

ACF文件如下内容

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 charret + 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、运行结果
相关推荐
小小龙学IT43 分钟前
Go 语言 cgo 与 C/C++ 互操作深度解析:从 fwlib 直连到工业数采网关实战系列
c语言·c++·golang
打工仔折腾 AI2 小时前
FaceFusion本地换脸实战:Windows整合包、模型选择与遮罩调参记录
人工智能·windows·后端·python·深度学习·性能优化·ai agent 实战
程序员老陆2 小时前
C++ 多线程通信方式全景:从共享内存到结构化协调
开发语言·c++
某不知名網友3 小时前
ROS2 核心通信:话题发布与订阅详解
开发语言·c++
C++ 老炮儿的技术栈3 小时前
char (*csConnectName)[256]; 和 char csConnectName [256] 有什么区别
java·c语言·开发语言·c++·人工智能·算法·c
大鹏说大话3 小时前
C++ STL 容器怎么选?vector、list、map、unordered_map 对比
开发语言·c++·list
JMchen3 小时前
性能优化——让Native代码飞起来
android·c++·性能优化
chenbingjie_c4 小时前
手撕 C++ priority_queue:二叉堆 + 模板仿函数 + 模板特化(保姆级逐函数拆解)
开发语言·c++
小小龙学IT4 小时前
C++ Redis 客户端深度解析(hiredis 与 redis-plus-plus)——工业数采实时缓存 C++ 侧实战
c++·redis·缓存
垆边人似月.4 小时前
华为机试题 :最长递增子序列题目
数据结构·c++·算法·华为