前言
在编译完成Protobuf项目后(如何编译Protobuf项目),接下来即可将编译好的库,导入到项目工程中使用。本文主要讲解如何将Protobuf库导入到虚幻中,并使用。
本文选用的Protobuf版本是protobuf-3.21.12
操作
- 创建C++空白项目
- 在项目Soruce文件夹下,添加ThirdParty文件夹,用于导入第三方Protobuf库
- 添加用于导入库的模块文件夹,命名为UEProtobuf(名称随意)
- 在文件夹内添加include(用于存放头文件)和lib(用于存放库)文件夹
- 创建UEProtobuf.Build.cs文件,用于构建模块配置
- 拷贝Protobuf项目中的源码头文件到模块include文件夹中
src文件夹中,只需要拷贝后缀是.h和.inc文件即可,其他可删除
- 拷贝库文件到模块的lib文件夹中
- 配置Build.cs文件将如下内容拷贝到文件中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
using UnrealBuildTool;
using System.IO;
public class UEProtobuf : ModuleRules
{
public UEProtobuf(ReadOnlyTargetRules Target) : base(Target)
{
Type = ModuleType.External;
PublicSystemLibraryPaths.Add(Path.Combine(ModuleDirectory, "lib"));
PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "include"));
PublicSystemLibraries.Add("libprotobuf.lib");
PublicSystemLibraries.Add("libprotoc.lib");
}
}
|
- 右键uproject文件,在菜单中选择刷新solution
使用Protobuf库
- 导入Protobuf库的模块
在项目的build文件中,加入模块UEProject
1
2
|
//ProtobufToturial.Build.cs文件中截取代码
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UEProtobuf" });
|
- 使用已经编译好的protobuf编译器(protoc.exe),将写好的protobuf文件编译成C++平台代码(这里需要你了解protobuf语法特点,并了解如何完成protobuf转换操作)。
protobuf文件内容如下:
1
2
3
4
5
|
syntax = "proto3";
message Phone {
int32 Number = 1;
string Name = 2;
}
|
- 将生成的头文件和源文件拷贝到虚幻工程项目的source文件夹中(路径关系根据需求可调整)
- 在Rider中(VS操作基本一样),将头文件与源文件引入项目,操作如下:
- 测试代码
在Gamemode中添加指令函数,并在源文件中定义指令函数,编写如下测试代码。
头文件内容
1
2
3
|
protected:
UFUNCTION(Exec)
void TestProtobuf();
|
源文件内容
1
2
3
4
5
6
7
8
9
10
11
12
|
void AProtobufToturialGameModeBase::TestProtobuf()
{
//声明Protobuf类型数据
Phone m_phone;
m_phone.set_number(100);
m_phone.set_name("这是一部iphone");
//输出数据
UE_LOG(LogTemp, Log, TEXT("%d"), m_phone.number());
//输出文本
UE_LOG(LogTemp, Log, TEXT("%s"), UTF8_TO_TCHAR(m_phone.name().c_str()));
}
|
编译工程时,会出现如下错误
1
2
3
|
inlined_string_field.h(430): [C4668] 没有将“GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE”定义为预处理器宏,用“0”替换“#if/#elif”
inlined_string_field.h(430): [C4668] 没有将“GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE”定义为预处理器宏,用“0”替换“#if/#elif”
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
2
3
4
5
6
7
|
#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
lhs->get_mutable()->swap(*rhs->get_mutable());
if (!lhs_arena_dtor_registered && rhs_arena_dtor_registered) {
lhs_msg->OnDemandRegisterArenaDtor(lhs_arena);
} else if (lhs_arena_dtor_registered && !rhs_arena_dtor_registered) {
rhs_msg->OnDemandRegisterArenaDtor(rhs_arena);
}
|
改后
1
2
3
4
5
6
7
8
|
//调整此段
#ifdef GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
lhs->get_mutable()->swap(*rhs->get_mutable());
if (!lhs_arena_dtor_registered && rhs_arena_dtor_registered) {
lhs_msg->OnDemandRegisterArenaDtor(lhs_arena);
} else if (lhs_arena_dtor_registered && !rhs_arena_dtor_registered) {
rhs_msg->OnDemandRegisterArenaDtor(rhs_arena);
}
|
再次编译即可通过
- 运行查看结果
启用工程,将地图模式设置为项目Gamemode,通过唤出指令进行测试,即可得到测试结果。
1
2
3
|
Cmd: TestProtobuf
LogTemp: 100
LogTemp: 这是一部iphone
|
引擎版本:5.1.1
Protobuf版本:3.21.12
此模块UE4和UE5均可使用,如果你需要应用到自己工程,只需要将ThirdParty拷走,重新编译即可。
网盘资源 提取码: 4dcm