UE5集成gRPC

news2025/1/16 16:13:08

最近有项目需要在UE5里做RPC,对比了thrift、gRPC、rcplib等开源rpc框架,由于习惯使用protobuf,故选择了gRPC。然而,Google出品也是一言难尽啊,最起码编译太繁琐了。

本次使用的gRPC版本为1.62.1,UE5.2,以插件的形式集成,支持DebugGame/DebugGame Editor/Development/Development Editor/Shipping(目前只测试这几个)。

插件免费,下载地址:【免费】UE5gRPC1.62.1插件资源-CSDN文库

测试案例下载地址:【免费】UE5gRPC插件测试案例资源-CSDN文库

0、目的

        本来已经有人在git上做了比较好的插件,但是,我们搞C++的,总想着都是开源的东西,最好自己也来封装一个可以把控的东东,用起来放心,有什么功能需要扩展也可以自己接着肝。

        了解一下如何一步一步封装起来的过程也是值得期待的事情,在能力范围内,最大的自由度总是带来无限的快感 ^_^

1、所谓坑位

  •  gRPC依赖的库zlib与boringssl-with-bazel(boringssl-with-bazel包括crypto、ssl,这2人起主要冲突)与UE5相关库的名字重定义冲突。
  •  gRPC编译动态库极其困难,1.62.1版本编译动态库会出现upb相关的符号丢失问题。

2、尝试解决

  • UE5的编译器选项AdditionalLinkerOptions,本来想模拟C++链接器的“/FORCE:MUTIPLE”,结果不起作用;
  • 将gRPC换成动态库,想着UE里的冲突库是静态库,可能动态加载Grpc可行,但是动态库就需要显示加载,很麻烦,而且gRPC编译动态库upb库符号导出会出问题。最终,将crypto、ssl以及zlib换成动态库尝试(毕竟就这几个报错集成不到UE里),结果动态库的导出文件.lib与对应的静态库.lib还是冲突。【后来反思了一下,这种想法是博主编译链接知识太菜了】
  • 初始想法是哪个库冲突就唯一化哪个库。一个办法就是将UE的库升级到gRPC官方推荐的boringssl-with-bazel;另一个方法就是将Grpc依赖的库zlib与boringssl-with-bazel换成UE引擎的ThirdParty的同名库。

最终,最后一种想法的最后一种方法尝试成功。

3、Cmake配置

CMAKE组里:CMAKE_INSTALL_PREFIX    D:/grpc

ABSL里的CXX_STD勾选上

配置UE5的OPENSSL+ZLIB

4、库编译

选择Release,右键ALL_BUILD生成(采用VS2019)

右键INSTALL生成

生成的gRPC库文件

5、插件目录结构

其中,libgrpc1.62.1是grpc库,LibGrpc是插件源码目录。

其中,helloworld.grpc.pb.cc和helloworld.grpc.pb.h,helloworld.pb.cc和helloworld.pb.h是proto文件生成的。

cmd里的指令如下,输出目录改成自定义的,其中用到的exe程序均在生成的库目录的 grpc/bin 下。不同语言之间要用到的RPC工具博主也生成了,都在bin里面,对应的指令大家自己百度一下即可,由于博主的客户端也是Cpp的,就共用了。

protoc.exe --grpc_out=输出目录 --plugin=protoc-gen-grpc=D:\grpc\bin\grpc_cpp_plugin.exe helloworld.proto

protoc.exe --cpp_out=输出目录helloworld.proto

6、LibGrpc.Build.cs

// Copyright Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;
using System.IO;

public class LibGrpc : ModuleRules
{
	public LibGrpc(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
		bEnableUndefinedIdentifierWarnings = false;

		PublicIncludePaths.AddRange(
			new string[] {
				// ... add public include paths required here ...
			}
			);
				
		PrivateIncludePaths.AddRange(
			new string[] {
				// ... add other private include paths required here ...
			}
			);
			
		PublicDependencyModuleNames.AddRange(
			new string[]
			{
				"Core",
				// ... add other public dependencies that you statically link with here ...
			}
			);
		
		PrivateDependencyModuleNames.AddRange(
			new string[]
			{
				"CoreUObject",
				"Engine",
				"Slate",
				"SlateCore",
				// ... add private dependencies that you statically link with here ...	
			}
			);
		
		DynamicallyLoadedModuleNames.AddRange(
			new string[]
			{
				// ... add any modules that your module loads dynamically here ...
			}
			);

		//set grpc library for Windows
		string GrpcPath = Path.GetFullPath(Path.Combine(ModuleDirectory, "../libgrpc1.62.1/"));
		//include the grpc header files
		string IncludePath = GrpcPath + "include/";
		PublicSystemIncludePaths.AddRange(new string[] { IncludePath });
		
		//use engine library
		AddEngineThirdPartyPrivateStaticDependencies(Target, "OpenSSL");
		AddEngineThirdPartyPrivateStaticDependencies(Target, "zlib");
		if (Target.Platform == UnrealTargetPlatform.Win64)
        {
			//add the grpc libs
			string LibPath = GrpcPath + "lib/Win64/";
			foreach (string file in Directory.GetFiles(LibPath))
			{
				PublicAdditionalLibraries.Add(file);
			}
		}
		else if (Target.Platform == UnrealTargetPlatform.Linux){
			System.Console.WriteLine("Not currently supported on Linux");
		}
		else // unsupported platform
		{
			System.Console.WriteLine("Only supported on Windows");
		}
	}
}

7、插件测试

采用Grpc自带的示例测试,helloworld.proto。

helloworld.grpc.pb.cc、helloworld.grpc.pb.h、helloworld.pb.cc和helloworld.pb.h是协议自生成的文档,greeter_server.cc可以封装到UE的内部组织里,比如将其逻辑写在FRunnable的子类里,然后暴露给BlueprintFunctionLibrary让蓝图调用。

使用之前需要测试全面,至少包括:DebugGame/DebugGame Editor/Development/Development Editor/Shipping,测试一下插件编译是否成功。

至此,UE5的gRPC插件封装完成,祝大家使用愉快,编译一次丝滑通过。

有问题随时联系我,共同踩坑,共同进步!

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

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

相关文章

面试stm32基础知识

1.ISP 第一步进入bootloader模式:先置BOOT0为高,BOOT1为低,再复位单片机进入bootloader模式,之后通过上位机下载程序; 第二步配置启动代码的地方:代码下载完毕后,置BOOT0为低,BOOT1…

【NTN 卫星通信】NTN的信关站应该建在哪些地方

1 概述 3GPP的卫星通信讨论了透传星和再生星两种方式。透传星方式,卫星主要是做为中继存在,基本上不做通信协议的处理。再生星方式,gNodeB的主要功能在卫星上,完成通信协议的主要内容。无论是透传星还是再生星,都需要通…

[C++]异常

基本使用 try {int a, b; std::cin >> a >> b;if(b 0) {throw std::runtime_error("unexpected zero");} else {cout << a / b << endl;}} catch(std::exception &e) { cout << "runtime_error: " << e.what() &…

战姬物语部署

一.准备环境 #关闭seliunx和防火墙 setenforce 0 systemctl stop firewalld systemctl disable firewalld #配置源&#xff0c;并安装常用工 curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo curl -o /etc/yum.repos.d/epel.repo …

用队列实现栈(力扣第225题)

#include "stdio.h" #include "stdbool.h" #include "string.h" #include "stdlib.h" #include "assert.h"//初始化队列 typedef int QueueDataType;typedef struct queue {QueueDataType val;struct queue* next; }Qnode;t…

信号处理相关知识

一&#xff1a; 1.序列——三种典型序列通过matlab绘图即可 2.数字信号的自变量一定是整数&#xff0c;幅度上取值是有限的状态&#xff08;不一定是整数&#xff09;。 3.抽取和插值 4.模拟正弦信号sin(wt):w是角频率&#xff0c;单位rad/s,f是频率w/2Π。 5.假设用采样周…

盒子模型之弹性盒模型

经常适用于手机端图标布局 display: flex;让这个盒子显示成弹性盒&#xff08;很适合移动端布局&#xff09; 影响&#xff1a;1.让里面的子元素默认横向排列 2.如果子元素是行内元素&#xff0c;则直接变成块元素 3.只有一个元素&#xff0c;margin: auto;自动居中 <!DOCT…

CDPR全力开发《巫师4》,吸取《2077》教训

爆料来啦&#xff01;CDPR全力开发《巫师4》&#xff0c;吸取《2077》教训&#xff01; CD Projekt Red&#xff08;CDPR&#xff09;今天透露&#xff0c;目前全公司都在专心致志地开发《巫师4》&#xff0c;而《赛博朋克2077》的续作暂时还在早期阶段。之前参与2077的大多数…

228 基于matlab的神经网络人脸识别

基于matlab的神经网络人脸识别。 人脸识别以视网膜、 虹膜、 指纹等生物特征的识别作为生物标识符。生物特征识别不很容易伪造、 放错位置。新型脸识别使用的方法 RobustPCA 和径向基函数网络。程序已调通&#xff0c;可直接运行。 228 人脸识别 生物特征识 神经网络 - 小红书 …

12. MyBatis(二)

源码位置&#xff1a;MyBatis_demo 上篇文章我们学习了MyBatis的定义以及增删查改操作&#xff0c;并且学习了如何在xml文件中编写SQL时使用#{}的方式将参数和对象的属性映射到SQL语句中&#xff0c;上篇的内容已经足以应对大部分场景&#xff0c;本篇文章我们就要学习一下MyBa…

Jmeter 测试Dubbo接口-实例

1、Dubbo插件准备 ①把jmeter-plugins-dubbo-2.7.4.1-jar-with-dependencies.jar包放在D:\apache-jmeter-5.5\lib\ext目录 ②重新打开Jmeter客户端 在线程组-添加-取样器-dubbo simple&#xff0c;添加dubbo接口请求 2、Jmeter测试lottery接口 ①配置zookeeper参数 由于dub…

MapReduce案例-电影网站数据统计分析

本文适合大数据初学者学习MapReduce统计分析业务问题的步骤和基础的MapReduce编程方法&#xff0c;初步掌握Hadoop对计算任务的管理。 本文末尾有全部数据集和完整代码连接。 1.准备工作 安装Hadoop:Hadoop 3.3.2 离线安装-CSDN博客 按照好Hadoop之后要检查一下datanode运行情况…

Python数据容器(三)

一.tuple&#xff08;元组&#xff09; 1.元组同列表一样&#xff0c;都可以封装多个、不同类型的元素在内。 但最大的不同点在于&#xff1a;元组一旦定义完成&#xff0c;就不可修改。 2.元组定义&#xff1a;定义元组使用小括号&#xff0c;且使用逗号隔开各个数据&#…

大气的免费wordpress模板

国产的wordpress模板&#xff0c;更适合中国人使用习惯&#xff0c;更符合中国老板的审美的大气wordpress企业官网建站模板。 WordPress模板&#xff0c;也称为主题&#xff0c;是用于定义WordPress网站或博客外观和功能的预设计文件集。这些模板使用HTML、CSS和PHP代码构建&a…

ARM之栈与方法

ARM之栈与方法 计算机中的栈是一种线性表&#xff0c;它被限定只能在一端进行插入和删除操作&#xff08;先进后出&#xff09;。通常将可以插入和删除操作的一端称为栈顶&#xff0c;相对的一端为栈底。 通常栈有递增堆栈&#xff08;向高地址方向生长&#xff09;、递减堆栈…

视频监控平台的超大任务文件导入功能,如何通过日志判断导入是否成功

目录 一、概述 &#xff08;一&#xff09;编写目的 &#xff08;二&#xff09;适用情况 &#xff08;三&#xff09;导入相关参数说明 二、文件导入说明 &#xff08;一&#xff09; 日志文件路径 &#xff08;二&#xff09;不同情况下的说明和提示 1、 所有数据正确…

便携式手提Camera Link 模拟源测试设备

便携式手提Camera Link 模拟源测试设备 平台简介 便携式手提CameraLink模拟源测试设备&#xff0c;以PCIe的Camera link 播出卡和X86主板为基础&#xff0c;构建便携式的手提设备。 平台默认操作系统为win7 64位系统&#xff1b;具备丰富的外设接口&#xff0c;如VGA、HDMI、千…

患者关系管理系统功能详解

脉购健康管理系统&#xff08;软件&#xff09;包含&#xff1a;客户开卡、健康档案、问卷调查、问诊表、自动设置标签、自动随访、健康干预、健康调养、历年指标趋势分析、疾病风险评估、饮食/运动/心理健康建议、同步检查报告数据、随访记录、随访电话录音、健康阶段总结、打…

ELK日志采集系统

1.什么是ELK ELK 是一套流行的数据搜索、分析和可视化解决方案&#xff0c;由三个开源项目组成&#xff0c;每个项目的首字母合起来形成了“ELK”这一术语&#xff1a; Elasticsearch (ES): Elasticsearch 是一个基于 Apache Lucene 构建的分布式、实时搜索与分析引擎。它能够…

AI绘画 究竟在哪些方面降低了门槛

AI绘画的产物是图像。图像对人类的认知、情感和文化发展起着重要的作用&#xff0c;包括信息传递、创造性表达、历史记录、审美享受和交流。 从原来的纸笔调色板到数字时代的数字板、绘图软件&#xff0c;再到AI绘画时代&#xff0c;任何人都可以用几行简单的文字创作出高质量…