首页 > 系统相关 >C++第五十七篇——RPC进程间通信

C++第五十七篇——RPC进程间通信

时间:2024-03-28 16:24:48浏览次数:21  
标签:status RPCConn return 间通信 RPC 第五十七 printf NULL

第一步:新建一个空项目

 第二步:新建一个IDL

 第三步:生成一个GUID,编写RPCConn.idl

 RPCConn.idl

import "oaidl.idl";
import "ocidl.idl";

[
    uuid(1BA624D4-DC7D-484C-AF8C-0EF86C4A0555),
    version(1.0)
]
interface RPCConn
{
    int Add(
        [in] int a,
        [in] int b
    );
    unsigned long long GetLastInputInfoTime();
}
View Code

 

第四步:右击RPCConn.idl进行编译

 

 将RPCConn_s.c和RPCConn_h.h拷贝到RPC的服务端,将RPCConn_c.c和RPCConn_h.h拷贝到RPC的客户端。

第五步:新建一个服务端空项目RPCServer,将RPCConn_s.c和RPCConn_h.h拷贝过去,并添加现有项。

 第六步:新建一个RPCServer.cpp

#include "RPCConn_h.h"
#include <Windows.h>
#include <iostream>
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")


int main()
{
    RPC_STATUS status = RPC_S_OK;
    // 注册接口
    status = RpcServerRegisterIf(
        RPCConn_v1_0_s_ifspec,            // 要注册的接口
        NULL,                            // 指向与EPV参数关联的UUID
        NULL                            // 管理器例程的入口点向量EPV
    );

    if (status != RPC_S_OK)
    {
        printf("注册接口失败。错误代码:0x%08X\n", status);
        return status;
    }
    printf("注册接口完成\n");
    // 使服务器在本地可用
    status = RpcServerUseProtseq(
        (RPC_WSTR)L"ncalrpc",
        RPC_C_PROTSEQ_MAX_REQS_DEFAULT,    // Protseq dependent parameter
        NULL                                // Always specify NULL here.
    );

    if (status != RPC_S_OK)
    {
        printf("指定使用协议失败。错误代码:0x%08X\n", status);
        return status;
    }
    printf("指定ncalrpc协议完成\n");
    // 获取绑定向量
    RPC_BINDING_VECTOR* rpcBindingVector;
    status = RpcServerInqBindings(&rpcBindingVector);
    if (status != RPC_S_OK)
    {
        printf("获取绑定向量失败。错误代码:0x%08X\n", status);
        return status;
    }
    printf("绑定向量完成\n");
    // 注册终结点
    status = RpcEpRegister(
        RPCConn_v1_0_s_ifspec,                // 注册终结点的接口
        rpcBindingVector,                    // 指定绑定句柄的向量
        NULL,                                // 指向服务器提供的对象UUID的向量指针
        NULL                                // 字符串注释指针
    );
    if (status != RPC_S_OK)
    {
        printf("注册终结点失败。错误代码:0x%08X\n", status);
        return status;
    }
    printf("注册终结点完成\n");
    printf("开始侦听客户端......\n");
    // 侦听客户端调用
    status = RpcServerListen(
        1,                                    // 服务器中创建和维护的最小线程数
        RPC_C_LISTEN_MAX_CALLS_DEFAULT,        // 建议的最大并发远程过程调用数
        0                                    //    控制监听返回的标志 0:在完成所有回调前不返回 !0:完成函数处理后立即返回
    );
    if (status != RPC_S_OK)
    {
        printf("侦听客户端调用失败。错误代码:0x%08X\n", status);
        return status;
    }
    return status;
}


int Add(
    /* [in] */ handle_t IDL_handle,
    /* [in] */ int a,
    /* [in] */ int b)
{
    printf("Calling Add:%d + %d = %d\n", a, b, a + b);
    return a + b;
}

unsigned long long GetLastInputInfoTime(
    /* [in] */ handle_t IDL_handle)
{
    LASTINPUTINFO lastInputInfo;
    lastInputInfo.cbSize = sizeof(lastInputInfo);
    GetLastInputInfo(&lastInputInfo);
    ULONGLONG time = GetTickCount64() - lastInputInfo.dwTime;
    printf("Time:%llu\n", time);
    return time;
}

/******************************************************/
/*         MIDL allocate and free                     */
/******************************************************/

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);
}
View Code

 

第七步:为RPCServer的链接器添加一个rpcrt4.lib文件

 第八步:将RPCServer设置为启动项目并运行起来,可以在任务管理器的进程中看到。

第九步:创建一个RPC客户端空项目,将RPCConn_c.c和RPCConn_h.h拷贝进去

 第十步:新建一个RPCClient.cpp

#include "RPCConn_h.h"
#include <Windows.h>
#include <iostream>

int main()
{
    RPC_STATUS status = RPC_S_OK;
    unsigned short* StringBinding;
    RPC_BINDING_HANDLE BindingHandle;
    status = RpcStringBindingCompose(
        NULL,                           // Object UUID
        (RPC_WSTR)L"ncalrpc",           // Protocol sequence to use
        NULL,                           // Server DNS or Netbios Name
        NULL,
        NULL,
        &StringBinding
    );
    if (status != RPC_S_OK)
    {
        printf("获取绑定字符串失败。错误代码:0x%08X\n", status);
        return status;
    }
    status = RpcBindingFromStringBinding(StringBinding, &BindingHandle);
    if (status != RPC_S_OK)
    {
        printf("获取绑定句柄失败。错误代码:0x%08X\n", status);
        return status;
    }
    RpcStringFree(&StringBinding);
    printf("请输入两个数字:\n");
    int a = 0, b = 0;
    scanf_s("%d%d", &a, &b);
    printf("%d + %d = %d\n", a, b, Add(BindingHandle, a, b));
    system("pause");
    return status;
}

/******************************************************/
/*         MIDL allocate and free                     */
/******************************************************/

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);
}
View Code

第十一步:为RPCClient的链接器添加一个rpcrt4.lib文件。

第十二步:将RPCClient设为一个启动项目并运行

 成功通信。

 

标签:status,RPCConn,return,间通信,RPC,第五十七,printf,NULL
From: https://www.cnblogs.com/smart-zihan/p/18101972

相关文章

  • gRpc
    一、gRpc是什么gRPC是一个开源的高性能远程过程调用(RPC)框架,调用远程服务可像调用方法一样简单,适用于多种环境和多种语言。gRPC基于HTTP/2协议标准,并使用Protobuf序列化机制,gRPC基于接口定义语言(IDL)进行定义,允许用户定义服务及其能够被远程调用的方法,gRPC框架支持多种开发语言......
  • 谈tcp,http,socket,rpc,grpc
    谈tcp,http,socket,rpc,grpc简介:计算机网络的五(七)层协议:物理层、数据链路层、网络层、传输层、(会话层、表示层)和应用层。tcp:是传输层协议,主要解决数据如何在网络中传输。http:是应用层协议,主要解决如何包装数据(文本信息),是建立在tcp协议之上的应用。tcp协议是以二进制数据流的形......
  • 代码随想录算法训练营第五十七/天 | 516. 最长回文子序列,647. 回文子串
     动态规划最强总结篇!如今动态规划已经讲解了42道经典题目,共50篇文章,是时候做一篇总结了。关于动态规划,在专题第一篇关于动态规划,你该了解这些! (opensnewwindow)就说了动规五部曲,而且强调了五部对解动规题目至关重要!这是Carl做过一百多道动规题目总结出来的经验结晶啊......
  • .Net 8.0 下的新RPC,IceRPC之接口定义语言 [Slice] VS [Protobuf]
    作者引言很高兴啊,我们来到了接口定义语言(IDL)篇,RPC之基石,有了它,可以在各种各种语言中实现RPC通讯。Slice和Protobuf是什么?IceRPC的核心是一个面向字节bytes的RPC框架:它可以轻松地发送携带字节的请求requests,并接收携带更多字节的响应responses.IceRPC以字节为中心......
  • HDFSRPC安全认证Token篇推广
    本文主要阐述HDFSRPC安全认证相关的实现。主要介绍Token相关的实现。写在前面相关bloghttps://blog.csdn.net/hncscwc/article/details/124722784https://blog.csdn.net/hncscwc/article/details/124958357Token由来在探究完Kerberos,我一直在想一个问题,rpcConnection已经完......
  • 通过XMLRpc控制海康VB2200视觉控制器自带光源接口
    在使用HikVB2200视觉控制器时,由于并未使用VisionMaster软件,但是使用了视觉控制器的光源接口。导致无法直接控制该光源接口。VB2200视觉控制器提供了一个IOController应用程序,其中对应的exe文件可以设置为对应光源接口的亮度等参数,基本满足需求。但是IOController只能设置......
  • gRPC简单示例
    gRPC概述gRPC是一种跨语言的RPC框架,之所以它能跨语言,是因为它基于protobuf描述对象实体和方法,最后通过protobuf编译器生成指定语言的代码。这样,就能通过一套protobuf声明生成多种语言的相同API,对于实现跨语言的RPC通信非常便利,同时也使用protobuf作为通信的序列化协议。如下通......
  • 进程间通信 之 管道
    目录什么是管道通信管道通信的特点匿名管道命名管道进程间通信的本质:让不同的进程看到同一份资源!什么是管道通信管道是Unix中最古老的进程间通信的形式。它是一种基于文件的通信形式,我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”。管道文件是一种......
  • ProtoBuf-gRPC实践
    目录介绍01.gRPC学习背景1.1为什么要学RPC1.2RPC是什么1.3网络库收益分析1.4学习计划说明1.5学习问题思考02.ProtoBuf的介绍2.1ProtoBuf是什么2.2ProtoBuf和json2.3ProtoBuf问题思考2.4ProtoBuf特点2.5ProtoBuf存储格式2.6ProtoBuf优缺点2.7创建pr......
  • 解决go项目引进etcd/clientv3的一个报错grpc版本过高的两个方法
    在使用etcd做服务注册和发现,编译时提示下列错误:#github.com/coreos/etcd/clientv3/balancer/pickerF:\Go\pkg\mod\github.com\coreos\[email protected]+incompatible\clientv3\balancer\picker\err.go:37:44:undefined:balancer.PickOptionsF:\Go\pkg\mod\github.com\coreos\e......