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);//可以获取对端的数据,比如状态或者其他
}
 

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 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、运行结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/743486.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode热题100】73. 矩阵置零(矩阵)

一.题目要求 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 二.题目难度 中等 三.输入样例 示例 1: 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0…

2024考研计算机考研复试-每日重点(第二十期)

公众号“准研计算机复试”,超全大佬复试资料,保姆级复试,80%的题目都是上岸大佬提供的。 研宝们,App更新啦! 计算机组成原理: 10.☆什么是数据存储的大端模式和小端模式? 大端模式:数…

github拉取项目找不到前端代码

今天从github上拉取了一个项目,使用docker部署在了服务器上, 代码正常运行,但是想在下载的项目中找前端代码遇到了问题,项目结构中的template模板只有一个页面,于是查看nginx配置文件 查看index.html 引入了一些js文件…

使用Julia及R语言生成正态分布的随机数字并写入CSV文件

在操作之前需要先下载Julia的Distributions包,这个包用于进行相关概率分布的函数调用。 在输入 ] 进入Julia包管理模式后输入: add Distributions 这里我使用我们自己实验室的实测数据 ,平均值0.67,方差0.11,数据分…

聚氨酯封孔剂因为热爱

忙忙碌碌又一天,对每个顾客都用心服务,因为热爱,所以不辛苦,因为热爱,即使无数遍的重复也不会厌倦。 聚氨酯封孔材料的主要性能特点: 1、粘度低,易渗入微小裂隙; 2、粘合能力很强,具有持久强粘结性; 3、柔韧性.越&am…

HCIP —— BGP 路径属性 (上)

目录 BGP 路径属性 1.优选Preferred-Value属性值最大的路由 2.优选Local-preference 属性数值大的路由 3.本地始发的BGP路由优先于其他对等体处学习到的路由。 4..优选AS_PATH属性值最短的路由 BGP 路径属性 BGP的路由选路是存在优选规则的,下图为华为官网提供…

2 配置虚拟机

1.打开VM,主页的界面如下,点击"创建新的虚拟机" 2.选择“自定义(高级)”,然后点击下一步,如下图所示: 3.下图直接点击“下一步” 4.下图的界面上,注意,不要选择…

【STL】stack栈容器与list链表容器

1.栈stack 栈具有先进后出的特性,最先进入的数据压在最底下,最后出来 2.list链表容器 list链表容器是一种双向链表,两端都可插入与删除,是双向访问迭代器,与vertor随机访问迭代器有不同的区别 reverse(&…

蓝桥杯-质因数问题

约数,又称因数:a % b 0,则b称为a的约数,包括1和a。 例如4的正约数有:1、2、4。6的正约数有:1、2、3、6。质因数: 质因数(素因数或质因子)在数论里是指能整除给定正整数(…

基于SpringBoot+MYSQL+Vue的校园管理系统

目录 1、前言介绍 2、主要技术 3、系统流程分析 3.1、操作流程 3.2、添加信息流程 3.3、删除信息流程 4、系统设计 4.1 系统体系结构 4.2开发流程设计 4.3 数据库设计原则 4.4 数据表 5、运行截图(部分) 5.1管理员功能模块 5.2用户功能模块 5.3院校管理员功能模块…

java-房屋信息网系统-209-(代码+说明)

转载地址: http://www.3q2008.com/soft/search.asp?keyword房屋信息网系统 本课题所确立的框架主要分为: 1、房屋信息发布。 发布房屋的信息包括新房信息、买卖房信息、二手房信息以及出租房屋的信息等。 2、房屋信息交流区。 提供一个给用户自由交流的一个空间。…

three.js 鼠标左右拖动改变玩家视角

这里主要用到了 一个方法 obj.getWorldDirection(); obj.getWorldDirection()表示的获取obj对象自身z轴正方向在世界坐标空间中的方向。 按下 W键前进运动&#xff1b; <template><div><el-container><el-main><div class"box-card-left…

bdd100k数据集格式转coco格式

最近在学习使用mmdetection&#xff0c;需要使用bdd100k数据集来训练网络&#xff0c;但是官网下载的数据集格式不是coco数据集&#xff0c;得自己转换数据集格式。 文章目录 一、bdd100k数据集下载二、bdd100k转coco脚本下载三、脚本使用 一、bdd100k数据集下载 数据集下载地…

UDP通讯测试

参考资料&#xff1a;UNIX网络编程 实验平台&#xff1a;PC为client&#xff0c;RaspberryPi为server 基本类型和接口函数&#xff0c;参考man手册 #include <sys/socket.h>struct sockaddr {sa_family_t sa_family; /* Address family */char sa_d…

Docker 笔记(五)--链接

这篇笔记记录了Docker 的Link。 官方文档&#xff1a; Legacy container links - Communication across links 目录 参考Legacy container linksConnect using network port mappingConnect with the linking systemThe importance of naming Communication across linksEnviro…

React Hooks 那些事儿

翻了波之前写的文章还有笔记&#xff0c;发现关于前端的文章并不多&#xff08;好歹也划水做过点前端开发&#xff09;。巧了&#xff0c;最近没什么好话题可写&#xff0c;做下 React Hooks 学习笔记吧。 Effect Hook 不得不说 Hook 的出现降低了我们在 React 中处理副作用&…

LDK加密狗的多种功能特点

LDK加密狗是一种在软件保护领域广泛应用的硬件加密设备&#xff0c;它为软件提供了强有力的版权保护&#xff0c;确保软件开发商的权益得到充分保障。本文将从LDK加密狗的工作原理、功能特点、应用场景以及未来发展等方面进行详细阐述。 LDK加密狗的工作原理基于硬件加密技术。…

深入理解Python中的面向对象编程(OOP)【第129篇—Scikit-learn的入门】

深入理解Python中的面向对象编程&#xff08;OOP&#xff09; 在Python编程领域中&#xff0c;面向对象编程&#xff08;Object-Oriented Programming&#xff0c;简称OOP&#xff09;是一种强大而灵活的编程范式&#xff0c;它允许开发者以对象为中心组织代码&#xff0c;使得…

为什么选择VR全景进行企业宣传,如何将VR全景运用在企业展示

引言&#xff1a; 随着科技的不断发展&#xff0c;VR全景技术逐渐成为企业宣传的热门选择。那么&#xff0c;为什么越来越多的企业选择使用VR全景技术进行宣传呢&#xff1f; 一&#xff0e;为什么选择VR全景技术进行企业宣传 1. 提升用户体验 VR全景技术可以为用户营造身临…

“SRP模型+”多技术融合在生态环境脆弱性评价模型构建、时空格局演变分析与RSEI 指数的生态质量评价及拓展应用教程

原文链接&#xff1a;“SRP模型”多技术融合在生态环境脆弱性评价模型构建、时空格局演变分析与RSEI 指数的生态质量评价及拓展应用教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247597452&idx5&snf723d9e5858a269d00e15dbe2c7d3dc0&chksmfa823c6…