虚幻引擎5引入Protocol Buffers 二(附工程源码)

前言

在编译完成Protobuf项目后(如何编译Protobuf项目),接下来即可将编译好的库,导入到项目工程中使用。本文主要讲解如何将Protobuf库导入到虚幻中,并使用。

本文选用的Protobuf版本是protobuf-3.21.12

操作

  1. 创建C++空白项目
  2. 在项目Soruce文件夹下,添加ThirdParty文件夹,用于导入第三方Protobuf库
  3. 添加用于导入库的模块文件夹,命名为UEProtobuf(名称随意)
  4. 在文件夹内添加include(用于存放头文件)和lib(用于存放库)文件夹
  5. 创建UEProtobuf.Build.cs文件,用于构建模块配置
  6. 拷贝Protobuf项目中的源码头文件到模块include文件夹中
    src文件夹中,只需要拷贝后缀是.h和.inc文件即可,其他可删除
  7. 拷贝库文件到模块的lib文件夹中
  8. 配置Build.cs文件将如下内容拷贝到文件中
 1using UnrealBuildTool;
 2using System.IO;
 3
 4public class UEProtobuf : ModuleRules
 5{
 6	public UEProtobuf(ReadOnlyTargetRules Target) : base(Target)
 7	{
 8		Type = ModuleType.External;
 9		
10		PublicSystemLibraryPaths.Add(Path.Combine(ModuleDirectory, "lib"));
11		
12		PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "include"));
13		
14		PublicSystemLibraries.Add("libprotobuf.lib");
15		PublicSystemLibraries.Add("libprotoc.lib");
16	}
17}
  1. 右键uproject文件,在菜单中选择刷新solution

使用Protobuf库

  1. 导入Protobuf库的模块

在项目的build文件中,加入模块UEProject

1//ProtobufToturial.Build.cs文件中截取代码
2PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UEProtobuf" });
  1. 使用已经编译好的protobuf编译器(protoc.exe),将写好的protobuf文件编译成C++平台代码(这里需要你了解protobuf语法特点,并了解如何完成protobuf转换操作)。 protobuf文件内容如下:
1syntax = "proto3";
2message Phone {
3    int32 Number = 1;
4    string Name = 2;
5}
  1. 将生成的头文件和源文件拷贝到虚幻工程项目的source文件夹中(路径关系根据需求可调整)
  2. 在Rider中(VS操作基本一样),将头文件与源文件引入项目,操作如下:
  3. 测试代码

在Gamemode中添加指令函数,并在源文件中定义指令函数,编写如下测试代码。

头文件内容

1protected:
2	UFUNCTION(Exec)
3	void TestProtobuf();

源文件内容

 1void AProtobufToturialGameModeBase::TestProtobuf()
 2{
 3	//声明Protobuf类型数据
 4	Phone m_phone;
 5	m_phone.set_number(100);
 6	m_phone.set_name("这是一部iphone");
 7
 8	//输出数据
 9	UE_LOG(LogTemp, Log, TEXT("%d"), m_phone.number());
10	//输出文本
11	UE_LOG(LogTemp, Log, TEXT("%s"), UTF8_TO_TCHAR(m_phone.name().c_str()));
12}

编译工程时,会出现如下错误

1  inlined_string_field.h(430): [C4668] 没有将“GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE”定义为预处理器宏,用“0”替换“#if/#elif”
2  inlined_string_field.h(430): [C4668] 没有将“GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE”定义为预处理器宏,用“0”替换“#if/#elif”
3  Microsoft.MakeFile.targets(45, 5): [MSB3073] 命令“"D:\Program Files\Epic Games\UE_5.1\Engine\Build\BatchFiles\Build.bat" ProtobufToturialEditor Win64 Development -Project="D:\Projectes\UE\ProtobufToturial\ProtobufToturial.uproject" -WaitMutex -FromMsBuild”已退出,代码为 6。

这个错误是因为需要在项目中配置预处理宏,用来管理是启用调试和非调试。修改方法如下:

到inlined_string_field.h文件中(双击错误跳转),将代码进行修改,参照如下:

1#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
2  lhs->get_mutable()->swap(*rhs->get_mutable());
3  if (!lhs_arena_dtor_registered && rhs_arena_dtor_registered) {
4    lhs_msg->OnDemandRegisterArenaDtor(lhs_arena);
5  } else if (lhs_arena_dtor_registered && !rhs_arena_dtor_registered) {
6    rhs_msg->OnDemandRegisterArenaDtor(rhs_arena);
7  }

改后

1//调整此段
2#ifdef GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
3  lhs->get_mutable()->swap(*rhs->get_mutable());
4  if (!lhs_arena_dtor_registered && rhs_arena_dtor_registered) {
5    lhs_msg->OnDemandRegisterArenaDtor(lhs_arena);
6  } else if (lhs_arena_dtor_registered && !rhs_arena_dtor_registered) {
7    rhs_msg->OnDemandRegisterArenaDtor(rhs_arena);
8  }

再次编译即可通过

  1. 运行查看结果

启用工程,将地图模式设置为项目Gamemode,通过唤出指令进行测试,即可得到测试结果。

1Cmd: TestProtobuf
2LogTemp: 100
3LogTemp: 这是一部iphone

引擎版本:5.1.1

Protobuf版本:3.21.12

此模块UE4和UE5均可使用,如果你需要应用到自己工程,只需要将ThirdParty拷走,重新编译即可。

网盘资源 提取码: 4dcm

文章评论