当时在学习虚幻下的TCP通讯,当时已经在unity中实现了一套完整的TCP通讯协议(客户端服务端),就把unity作为测试目标主机来使用。因为涉及到了跨语言数据序列化/反序列化,就使用了业界常用的protobuf协议,来让其相互通讯。

下面的两个链接,是参考文章:

虚幻引擎随笔:接入 Google Protobuf 库

使用Protobuf+Websocket构建Unreal与Python服务器的通信

可以参考上面这两篇文章,学习如何通过源码构建导入。

问题

因为虚幻使用的C++,可以直接通过下载c++源码或者编译好的使用,但是protobuf v22.0+之后的版本,官方不再提供对应语言的分支,需要下载完整版进行构建。这里使用了vcpkg进行构建(会落后于gihub版本),操作相对简单,会把相关依赖导入。

22.0+版本之后会把abseil被整体分离,需要单独导入到unreal里。即使是把abseil导入到虚幻内,在代码编译时,会因为内部函数报错。

同时代码编译器会在cpp下产生如下警告:(这个问题可使用编辑器提示修复)

这两个问题会导致虚幻无法正确编译。到这,其实可以使用21.10版本,这个版本不需要复杂的处理,仍然可用。或者继续使用22.1+版本,修改abseil文件,使其支持。

上面的原因,在protobuf的issue中提交过一个。但是没有解决方案

https://github.com/protocolbuffers/protobuf/issues/16450

最终,通过google搜索(在这里diss百度,啥也搜不到),在虚幻论坛上搜索到了这个问题的讨论:

https://forums.unrealengine.com/t/abseil-cpp-absl-in-thirdparty-redefinition-error/1794996

二楼回复知道了如何修改宏定义,来适配UE5。

需要修改两个文件: btree.hbtree_container.h文件。

修复

原因

absl/container/internal/btree. container.h absl/container/internal/btree. h文件中定义了函数 verify() 与UE5中的verify(expr) 宏定义冲突。

修复

在这两个文件在函数定义上下文中,取消UE5的宏定义。以下代码仅供参考,不同版本可能行数和位置不同。

  • btree.h 文件的第 1579 行左右,修改后:

#ifdef verify
#undef verify
#endif
  // Verifies the structure of the btree.
  void verify() const;
#ifndef verify
#define verify(expr)			UE_CHECK_IMPL(expr)  // copy from line 221 of /Engine/Source/Runtime/Core/Public/Misc/AssertionMacros.h
#endif
  • btree.h 文件的第 2610 行左右,修改后:

#ifdef verify
#undef verify
#endif
template <typename P>
void btree<P>::verify() const {
  assert(root() != nullptr);
  assert(leftmost() != nullptr);
  assert(rightmost() != nullptr);
  assert(empty() || size() == internal_verify(root(), nullptr, nullptr));
  assert(leftmost() == (++const_iterator(root(), -1)).node_);
  assert(rightmost() == (--const_iterator(root(), root()->finish())).node_);
  assert(leftmost()->is_leaf());
  assert(rightmost()->is_leaf());
}
#ifndef verify
#define verify(expr)			UE_CHECK_IMPL(expr)  // copy from line 221 of /Engine/Source/Runtime/Core/Public/Misc/AssertionMacros.h
#endif
  • btree_container.h 文件的第 225 行左右,修改后:

#ifdef verify
#undef verify
#endif
  void verify() const { tree_.verify(); }
#ifndef verify
#define verify(expr)			UE_CHECK_IMPL(expr)  // copy from line 221 of /Engine/Source/Runtime/Core/Public/Misc/AssertionMacros.h
#endif

至此,修复完成。

参考仓库

在UrealEngine论坛上的那个问题讨论三楼,有开发者放了一个仓库参考,可以参考一下。

引用回复:我正在使用 UE5.3.2,如果您正在构建一个独立的应用程序,threepotato 的解决方案可以工作,但就我而言,我正在构建一个插件,它在开发过程中工作正常,但如果您尝试打包您的 plugin.so 会导致失败我尝试了一种更激进的方法:我只是删除了 thost 两个验证函数,它们似乎仅用于测试。此外,我将库上传到 github 并附有一些构建说明。

https://github.com/ibreathebsb/ue5-protobuf

同时也放上我修改后的仓库,供各位开发者参考。

github:

https://github.com/ProgramBase/ProtobufAndAbseil-Unreal5

gitee:

https://gitee.com/RSJWY/protobuf-and-abseil-unreal5