UE5集成gRPC

ops/2024/10/19 14:45:53/

最近有项目需要在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.protoprotoc.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 Windowsstring GrpcPath = Path.GetFullPath(Path.Combine(ModuleDirectory, "../libgrpc1.62.1/"));//include the grpc header filesstring IncludePath = GrpcPath + "include/";PublicSystemIncludePaths.AddRange(new string[] { IncludePath });//use engine libraryAddEngineThirdPartyPrivateStaticDependencies(Target, "OpenSSL");AddEngineThirdPartyPrivateStaticDependencies(Target, "zlib");if (Target.Platform == UnrealTargetPlatform.Win64){//add the grpc libsstring 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.ppmy.cn/ops/9719.html

相关文章

字符串加密

描述 这是一个古老的字符串加密方法,给定两个长度不超过100个字符的字符串,判断是否可以把其中一个重排,然后对26个字母做一个一一映射,使得两个字符串相同。 再进行映射:例如 每个字母映射到前一个字母(B…

SpringBoot项目创建,详细流程

一、前言 Spring Boot是一个开源的Java框架,由Pivotal团队(现为VMware旗下)开发,通过提供默认配置和一系列启动器(starters)来简化项目配置,使得开发者能够快速启动和运行Spring应用程序。 ‍ …

ubunt18.04安装ROS避坑指南

1 前言: 本文是ubunt18.04下安装ros的,如果想使用ros2,请看我的下一篇文章,ubunt18.04安装ROS2 本来是不该写的,有官方文档,还有很多大神的分析。但里面的坑太多,我考虑了一下,还是想记录下避免下次在跳泥…

网卡接收数据的关键过程

网卡接收数据的关键过程 网卡中断处理网络软中断处理协议栈处理传输层处理 Linux内核tracers的实现原理与应用 前年ftrace for io /去年ftrace for mm/今年ftrace for network.今年ftrace也被深度定制加强。 在这篇文章中,我们将深入探讨网卡接收数据的完整过程,了解数据是如何…

Java中的设计模式在代码重构中的应用

设计模式是在软件开发中经常使用的一种经验总结,用于解决在特定上下文中重复出现的问题。在代码重构中,设计模式可以帮助我们改善代码的结构、可读性和可维护性。 下面是几个常见的设计模式及其在代码重构中的应用。 1. 单例模式(Singleton …

SimSiam(CVPR 2021)原理与代码解析

paper:Exploring Simple Siamese Representation Learning official implementation:https://github.com/facebookresearch/simsiam 本文的创新点 本文提出了一种名为SimSiam的简单孪生网络(Siamese network)结构,用…

【行为型模式】状态模式

一、状态模式概述 状态模式的定义:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。(对象行为型) 策略模式和状态模式是双胞胎,在出生时才分开。 策略模式是围绕可以互换的算法来创建成功业务的。状态模式走的是更崇高的路&#xff0…

MySQL-知识点详解

本文简要介绍了MySQL数据库的关键内容,包括数据类型、SQL语句、索引类型以及数据库优化等方面。详细讨论了各种数据类型,比较了DATETIME和TIMESTAMP类型,解释了SQL语句的执行顺序和数据库连接方式,介绍了MySQL索引的概念和优缺点&…