当前位置: 首页 > news >正文

【Windows】RPC调用过程实例详解

概述:windows 创建 RPC调用过程实例详解
参考文章:Remote procedure call (RPC)(远程过程调用 (RPC)) - Win32 apps | Microsoft Learn

RPC

文章目录

    • 0x01、生成 UUID 和模版(IDL)文件
    • 0x02、添加 acf 文件
    • 0x03、编译 idl 文件
    • 0x04、客户端
      • main.cpp
    • 0x05、服务端
      • main.cpp
    • 0x06、编译并运行
    • 0x07、运行示例
      • Client
      • Server

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 文件

  1. 打开 visual studio,新建一个空项目

  2. 空项目中添加上述 idl文件 和 acf文件
    接口工程

  3. 编译项目

  4. 生成 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

  1. 先运行 server.exe
  2. 在 client.exe 目录运行 client -ip 192.168.106.128 来启动客户端程序并与服务器端相连
  3. 在 client 的窗口输入任意字符串,回车后可看到server窗口上有显示
  4. 在 client 窗口内 输入 exit 或 quit, server 窗口关闭

0x07、运行示例

Client

Client截图

Server

Server截图

相关文章:

【Windows】RPC调用过程实例详解

概述&#xff1a;windows 创建 RPC调用过程实例详解 参考文章&#xff1a;Remote procedure call (RPC)&#xff08;远程过程调用 (RPC)&#xff09; - Win32 apps | Microsoft Learn 文章目录 0x01、生成 UUID 和模版(IDL)文件0x02、添加 acf 文件0x03、编译 idl 文件0x04、客…...

动手学强化学习第2章多臂老虎机

2.1简介 多臂老虎机问题可以被看作简化版的强化学习问题。但是其只有动作和奖励没有状态信息&#xff0c;算是简化版的强化学习问题。 2.2问题介绍 2.2.1问题定义 在多臂老虎机(MAB)问题中&#xff0c;有一个有K根拉杆的老虎机&#xff0c;拉动每一根拉杆都对应一个关于奖励…...

钡铼BL124EC实现EtherCAT转Ethernet/IP的优势

钡铼技术的BL124EC是一款用于将EtherCAT从站转换为Ethernet/IP从站的网关设备。它是钡铼技术开发的高性能、可靠的工业自动化通信解决方案之一。 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; BL124EC网关可以应用于多种工业自动化场景&#xff0c;以下…...

使用IntelliJ Idea必备的插件!

趁手的工具让开发事半功倍&#xff0c;好用的IDEA插件让效率加倍。 今天给大家分享几个优秀的IDEA插件。 插件安装 首先得知道在IDEA哪安装插件&#xff1f; 点击File---->Settings---->找到Plugins标签&#xff0c;即可搜索想要的插件进行安装了。 现在来看下有哪些值…...

代码随想录算法训练营第23期day19| 654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

目录 一、&#xff08;leetcode 654&#xff09;最大二叉树 二、&#xff08;leetcode 617&#xff09;合并二叉树 三、&#xff08;leetcode 700&#xff09;二叉搜索树中的搜索 四、&#xff08;leetcode 98&#xff09;验证二叉搜索树 一、&#xff08;leetcode 654&…...

第四章 字符串part02 28. 实现strStr() 459. 重复的子字符串

第四章 字符串part02 28. 实现strStr() 459. 重复的子字符串 一、28. 实现strStr() 题目链接&#xff1a;https://leetcode.cn/problems/repeated-substring-pattern/ 题目介绍&#xff1a; 给定一个非空的字符串 s &#xff0c;检查是否可以通过由它的一个子串重复多次构成。…...

设计模式 - 状态模式

目录 一. 前言 二. 实现 一. 前言 状态模式&#xff08;State Pattern&#xff09;&#xff1a;它主要用来解决对象在多种状态转换时&#xff0c;需要对外输出不同的行为的问题。状态和行为是一一对应的&#xff0c;状态之间可以相互转换。当一个对象的内在状态改变时&#x…...

【vim 学习系列文章 9 -- .vim 脚本文件开发学习】

文章目录 .vimrc 介绍.vim 脚本文件开发 .vimrc 介绍 在Vim中&#xff0c;你可以将一系列的Vim命令和设置写入一个脚本文件中&#xff0c;并使用:source命令来运行它。这种脚本文件通常被称为vimrc文件&#xff0c;因为它的默认名称是.vimrc。通常&#xff0c;我们将这个文件放…...

NAT模式和桥接模式的区别

NAT模式和桥接模式的区别 NAT模式和桥接模式都是虚拟机网络配置的两种方式&#xff0c;主要区别在于虚拟机与外部网络交互的方式不同。 NAT&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09;模式&#xff1a;在这种模式下&#xff0c;虚拟机和宿主…...

应对出海安全合规挑战,兆珑科技为什么选择了亚马逊云科技?

在中国企业出海进程中&#xff0c;安全合规是企业面临的首要挑战。尤其是当企业业务涉及金融相关领域时&#xff0c;面临着最为严苛的安全合规要求。 深圳兆珑科技有限公司是一家全球化的物联网生态企业&#xff0c;其业务覆盖100多个国家和地区&#xff0c;在欧洲、南美、亚太…...

Allegro基本规则设置指导书之Spacing规则设置

进入规则设置界面 1.设置Line 到其他的之间规则: 2.设置Pins 到其他的之间规则: 3.设置Vias 到其他的之间规则:...

使用【Blob、Base64】两种方式显示【文本、图片、视频】 使用 video 组件播放视频

Blob 显示 Blob 对象的类型是由 MIME 类型&#xff08;Multipurpose Internet Mail Extensions&#xff09;来确定的。MIME 类型是一种标准&#xff0c;用于表示文档、图像、音频、视频等多媒体文件的类型。以下是一些常见的 Blob 对象类型&#xff1a; text/plain&#xff1…...

深度学习_1_基本语法

数据结构 代码&#xff1a; import torchx torch.arange(12)##产生长度为12的一维张量print(x)##X x.resize(3, 4)##被弃用##print(X)y torch.reshape(x, (3, 4))##修改向量为矩阵&#xff0c;一维变二维print(y)print(y.size())xx torch.zeros((2, 3, 4))##三维矩阵&…...

c#设计模式-行为型模式 之 中介者模式

&#x1f680;简介 又叫调停模式&#xff0c;定义一个中介角色来封装一系列对象之间的交互&#xff0c;使原有对象之间的耦合松散&#xff0c;且可以独立地改变它们之间的交互。 从下右图中可以看到&#xff0c;任何一个类的变 动&#xff0c;只会影响的类本身&#xff0c;以及…...

小程序uView2.X框架upload组件上传方法总结+避坑

呈现效果: 1.1单图片上传 1.2多图片上传 前言:相信很多人写小程序会用到uView框架,总体感觉还算OK吧,只能这么说,肯定也会遇到图片视频上传,如果用到这个upload组件相信你,肯定遇到各种各样的问题,这是我个人总结的单图片和多图片上传方法. uView2.X框架:uView 2.0 - 全面兼容…...

人脸检测及追踪回顾

轻量级人脸检测 代码地址 人脸追踪 代码地址 MNN框架部署文档 文档地址...

虚拟环境和包

目录 12. 虚拟环境和包 12.1. 简介 12.2. 创建虚拟环境 12.3. 使用 pip 管理包 12. 虚拟环境和包 12.1. 简介 Python 应用程序经常会使用一些不属于标准库的包和模块。应用程序有时候需要某个特定版本的库&#xff0c;因为它需要一个特定的 bug 已得到修复的库或者它是使用…...

springboot配置文件读取

项目配置文件 怎么说呢&#xff0c;给了个项目&#xff0c;他启动了&#xff0c;然后我看不懂为啥能够启动项目这样 很迷茫&#xff0c;为啥能够成功启动呢项目&#xff0c;为啥项目有properties也要有yml呢&#xff1f; 问题处理 首先&#xff0c;properties的配置的优先级…...

纵享丝滑!Cesium + ffmpegserver 生成高质量动态视频【逐帧生成】

工作中需要提供一些在三维场景下的视频动画素材&#xff0c;屏幕录制会出现掉帧等其他问题&#xff0c;看到 ffmpegserver 后&#xff0c;眼前一亮 Cesium ffmpegserver 生成高质量视频 1.自建 ffmpegserver 首先&#xff0c;克隆 ffmpegserver 仓库代码 git clone https://…...

Linux下C++编程-进度条

引言&#xff1a;本篇主要在linux下的C实现进度条的功能。按照多文件编程&#xff0c;同时使用Makefile文件完成多文件的编译、连接。 首先创建头文件&#xff1a; 1. progress.h #pragma once #include <iostream> #include <cstring> #include <iomanip>…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...

消防一体化安全管控平台:构建消防“一张图”和APP统一管理

在城市的某个角落&#xff0c;一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延&#xff0c;滚滚浓烟弥漫开来&#xff0c;周围群众的生命财产安全受到严重威胁。就在这千钧一发之际&#xff0c;消防救援队伍迅速行动&#xff0c;而豪越科技消防一体化安全管控平台构建的消防“…...