UE5集成gRPC

最近有项目需要在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.mfbz.cn/a/560694.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

二分答案复习

y总二分查找算法模板 int bsearch_1(int l, int r) {while (l < r){int mid l r >> 1;//性质在右边&#xff0c;区间划分成[l, mid]和[mid 1, r]if (check(mid)) r mid;else l mid 1;}return l; }int bsearch_2(int l, int r) {while (l < r){int mid l r …

科普馆VR技术展现安全场景,构建安全教育新标杆!

随着VR技术的快速发展&#xff0c;其所衍生出的互动装置&#xff0c;悄无声息地渗透进了我们生活的每个角落&#xff0c;就连那严谨而重要的安全教育领域&#xff0c;也没能逃出这神奇魔法的“魔爪”&#xff0c;这种VR互动设备简直就是安全知识传递的小能手&#xff0c;那么&a…

SpringCloud系列(7)--Eureka服务端的安装与配置

前言&#xff1a;上一章节我们介绍了Eureka的基础&#xff0c;本章节则介绍Eureka服务端的安装与配置 Eureka架构原理图 1、创建Eureka Server端服务注册中心模块 (1)在父工程下新建模块 (2)选择模块的项目类型为Maven并选择模块要使用的JDK版本 (3)填写子模块的名称&#xf…

llama-factory SFT 系列教程 (四),lora sft 微调后,使用vllm加速推理

文章目录 文章列表&#xff1a;背景简介llama-factory vllm API 部署融合 lora 模型权重 vllm API 部署HuggingFace API 部署推理API 部署总结 vllm 不使用 API 部署&#xff0c;直接推理数据集 tenplatevllm 代码部署 文章列表&#xff1a; llama-factory SFT系列教程 (一)&a…

SpringMVC(三)【REST 风格】

1、REST 风格 1.1、REST 简介 REST&#xff08;Representational State Transfer&#xff09;&#xff0c;表现形式状态转换 在开发中&#xff0c;它其实指的就是访问网络资源的格式 1.1.1、传统风格资源描述形式 http://localhost/user/getById?id1http://localhost/user…

18 统计网站每日的访问次数

1.将竞赛的数据上传HDFS,查看数据的格式 通过浏览器访问hdfs,查看该文档前面的部分数据 每条数据的字段值之间使用逗号隔开的 &#xff0c;最终时间是第五个自动&#xff0c;获取第五个字段值的中的年月日。 2.通过Idea创建项目mr-raceData ,基础的配置 修改pom.xml,添加依赖 …

一文读懂uniapp中的tabBar底部导航

目录 1. 基本知识2. Demo 1. 基本知识 UniApp 中的 tabBar 是用来在应用程序底部显示可切换的选项卡的组件&#xff0c;通常用于实现底部导航栏 允许用户通过点击不同的选项卡来切换应用程序的不同页面或功能模块 其代码如下&#xff1a; "tabBar":{"color&q…

HoloLens2的Unity应用在电脑上发布成安装包,然后通过wifi安装到设备

一、VS工程中的鼠标右键 二、发布——>创建应用程序包 三、选择【旁加载】 四、选择签名方法&#xff1a; 五、选择和配置包 六、创建完毕 七、网络连接设备 八、登录设备 九、安装app

spring高级篇(二)

1、Aware和InitializingBean Aware和InitializingBean都与Bean的生命周期管理相关。 Aware接口: 概念: Aware接口是Spring框架中的一个标记接口&#xff0c;它表示一个类能够感知到&#xff08;aware of&#xff09;Spring容器的存在及其特定的环境。Spring框架提供了多个Awar…

Android自带模拟器如何获得ROOT权限

如果在模拟器中不能切换到root权限&#xff0c;很可能是镜像使用的不对。 一.选择镜像标准&#xff1a; 1.运行在PC端选X86_64镜像&#xff0c;才能流畅运行 2.不带google api的镜像 二.步骤 在虚拟机管理器中新建AVD&#xff0c;并下载符合要求的镜像文件 三.验证

shell脚本编程的例子(55例子)-3

第三部分&#xff1a;eg32-eg50shell例子。开放一周后启用vip阅读了。…… ^v^ Eg32、while/until/for经典例子 #!/bin/bash ## filename: while-infinite_loops.sh while true; do sleep 5 echo "infinite loops [ hit CTRLC to stop]" done Eg33、while/…

Rokid AR Lite空间计算套装发布,软硬件全面升级推动居家、出行、户外场景大规模应用

4月20日&#xff0c;以“好玩、好看、好上头”为主题的Rokid Open Day 2024发布会在杭州举行&#xff0c;Rokid对外正式发布新一代AR Lite空间计算套装&#xff0c;分享了近期Rokid在AR开发者生态和数字文化领域的进展和成果&#xff0c;并宣布了多项跨行业重磅合作。作为中国代…

PS-ZB转座子分析流程2-重新分析并总结

数据处理 数据质控 随机挑出九个序列进行比对&#xff0c;结果如下&#xff1a; 所有序列前面的部分序列均完全相同&#xff0c;怀疑是插入的转座子序列&#xff0c;再随机挑选9个序列进行比对&#xff0c;结果如下&#xff1a; 结果相同&#xff0c;使用cutadapt将该段序列修…

OerOerlikonTCO1200欧瑞康LPCVD system操作使用说明

OerOerlikonTCO1200欧瑞康LPCVD system操作使用说明

常见的经典目标检测算法

目标检测是计算机视觉领域的一个核心任务&#xff0c;它涉及到识别图像中的物体并确定它们的位置。以下是一些常见的经典目标检测算法&#xff1a; R-CNN系列 R-CNN&#xff08;Region-based Convolutional Neural Network&#xff09;是一种用于目标检测的算法&#xff0c;它…

PyQt5开发的DSP信号仿真系统

PyQt5开发的DSP信号仿真系统 1、效果图 2、功能 具备的功能: 1、生成基础信号波形[正弦波,脉冲函数,阶跃函数,斜坡函数, 锯齿波,方波,常见非周期波形,sinc函数] 2、各基础波形可以叠加 3、可展示FFT频谱、信号卷积、功率频谱密度估计 4、可以读取音频信号及分析 5、各…

第23天:安全开发-PHP应用后台模块SessionCookieToken身份验证唯一性

第二十三天 一、PHP后台身份验证模块实现 二、Cookie&Session技术&差异 1.生成cookie的原理图过程&#xff1a;见上图 客户端向服务器发送HTTP请求。服务器检查请求头中是否包含cookie信息。如果请求头中包含cookie信息&#xff0c;则服务器使用该cookie来识别客户端…

Android Studio Iguana | 2023.2.1配置优化

一. 前言 本篇文章记录最新版本的Android Studio的配置优化&#xff0c;写这篇文章的是由于电脑中的AS工具更新版本覆盖安装后&#xff0c;AS会经常卡死&#xff0c;Debug的时候也经常莫名其妙的断掉&#xff0c;非常影响工作效率&#xff0c;所以重新把配置环境整理一下&#…

保姆级教程!QRCNN-BiLSTM一键实现多变量回归区间预测!区间预测全家桶再更新!

​ 声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 今天对我们之前推出的区间预测全家桶进行…

详解数据在内存中的存储

系列文章目录 第一章 C语言基础知识 第二章 C语言控制语句 第三章 C语言函数详解 第四章 C语言数组详解 第五章 C语言操作符详解 第六章 C语言指针详解 第七章 C语言结构体详解 文章目录 1. 数据类型 1.1 基本数据类型 1.2 派生数据类型 2. 整形在内存中的存储 2.1 …