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、运行结果
相关推荐
机器视觉知识推荐、就业指导11 分钟前
QML 批量创建模块 【Repeater】 组件详解
前端·c++·qml
橙橙子23036 分钟前
c++柔性数组、友元、类模版
开发语言·c++·柔性数组
阳光_你好1 小时前
请详细说明opencv/c++对图片缩放
c++·opencv·计算机视觉
杰克逊的黑豹2 小时前
不再迷茫:Rust, Zig, Go 和 C
c++·rust·go
Y.O.U..2 小时前
今日八股——C++
开发语言·c++·面试
抛物线.2 小时前
inhibitor_tool
windows
Zhichao_972 小时前
【UE5 C++课程系列笔记】33——商业化Json读写
c++·ue5
云边有个稻草人3 小时前
【C++】第八节—string类(上)——详解+代码示例
开发语言·c++·迭代器·string类·语法糖auto和范围for·string类的常用接口·operator[]
宋冠巡3 小时前
Windows安装Docker(Docker Desktop)
windows·docker·容器
惊鸿一博3 小时前
c++ &&(通用引用)和&(左值引用)区别
开发语言·c++