ptotothreads 源码_虚幻4 Protobuf源码集成

更新记录

2018-02-27 更新

Protobuf 更新到 3.5.1

增加一些其他的错误处理

插件源码

直接在项目中集成 libprotobuf 的源码,方便使用

测试平台

已测试通过

Win32, Win64

Android

MAC

iOS

未测试

Linux

如何使用

将 Source\Protobuf 文件夹复制到自己的项目的Source目录下

修改自己项目的 .build.cs 文件,在 PublicDependencyModuleNames 中增加 Protobuf 模块,并增加 bEnableShadowVariableWarnings = false; bEnableUndefinedIdentifierWarnings = false;,禁掉警告

以下记录完整步骤

提取 libprotobuf 源码

到 protobuf releases

下载 protobuf-cpp 源码包

用 CMake 生成 Visual Studio 工程

cd /D protobuf-3.x.x\cmake

cmake.exe -G "Visual Studio 14 2015 Win64" .将工程 libprotobuf 中用到的源码文件和对应的头文件提取出来

修改 libprotobuf 源码

主要是去掉两个宏开关 GOOGLE_PROTOBUF_NO_RTTI 和 HAVE_PTHREAD

去掉 HAVE_PTHREAD 宏

在非 Windows 平台下都要打开 HAVE_PTHREAD 宏

打开 google/protobuf/stubs/common.cc,把两个地方的 elif defined(HAVE_PTHREAD) 改成 #else

并且把第一处以下两行代码删除

#else#error "No suitable threading library available."

去掉 GOOGLE_PROTOBUF_NO_RTTI 宏

在所有平台下都要禁用 RTTI,因为 UE4 禁用了 C++ 的运行时类型识别(typeid 和 dynamic_cast)

打开 google/protobuf/arena.h,将

#ifndef GOOGLE_PROTOBUF_NO_RTTI#define RTTI_TYPE(type) (&typeid(type))#else#define RTTI_TYPE_ID(type) (NULL)#endif

改为

#define RTTI_TYPE_ID(type) (NULL)

打开 google/protobuf/generated_message_reflection.h,将

#if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI))return NULL;

#elsereturn dynamic_cast(from);

#endif

改为

return NULL;

#if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI))bool ok = &T::default_instance() == from->GetReflection()->GetMessageFactory()->GetPrototype(from->GetDescriptor());

return ok ? down_cast(from) : NULL;

#elsereturn dynamic_cast(from);

#endif

改为

bool ok = &T::default_instance() == from->GetReflection()->GetMessageFactory()->GetPrototype(from->GetDescriptor());

return ok ? down_cast(from) : NULL;

打开 google/protobuf/stubs/casts.h,删除以下两处代码

#if !defined(NDEBUG) && !defined(GOOGLE_PROTOBUF_NO_RTTI)assert(f == NULL || dynamic_cast(f) != NULL); // RTTI: debug mode only!#endif

#if !defined(NDEBUG) && !defined(GOOGLE_PROTOBUF_NO_RTTI)// RTTI: debug mode only!assert(dynamic_cast(&f) != NULL);

#endif

替换 LIBPROTOBUF_EXPORT 宏

将代码里除 google/protobuf/stubs/port.h 中的 LIBPROTOBUF_EXPORT 宏替换为 PROTOBUF_API

将代码里的两处 #elif defined(PROTOBUF_USE_DLLS) 替换为 #elif defined(PROTOBUF_API)

禁用编译警告

因为 UE4 会将一些编译警告当成错误,所以要将编译过程中 libprotobuf 中的警告禁用掉

在 Protobuf 模块的编译描述文件 Protobuf.build.cs 中增加

bEnableShadowVariableWarnings = false;

bEnableUndefinedIdentifierWarnings = false;

在 google/protobuf/map_field.h 文件开头增加

#ifdef _MSC_VER#pragma warning(disable: 4661)#endif//_MSC_VER

check 宏冲突问题

打开 google/protobuf/stubs/type_traits.h,将 check 宏改名为 g_check,如下

// BEGIN GOOGLE LOCAL MODIFICATION -- check is a #define on Mac.// #undef check// END GOOGLE LOCAL MODIFICATION

static yes g_check(const B*);

static no g_check(const void*);

enum {

value = sizeof(g_check(static_cast(NULL))) == sizeof(yes),

};

noexcept 关键字问题

Protobuf 从 3.5 版本开始,逐渐使用 C++11 语法,其中就使用了 noexcept 关键字,但是在虚幻中默认是不使用异常处理的,这样就会导致编译失败,错误为

error C4577: 在未指定异常处理模式的情况下使用了 "noexcept";不一定会在异常时终止。指定 /EHsc

有以下几种改法

第一种是在 build.cs 中打开 bEnableExceptions 开关,本文中就是使用了这个方法

第二种是将 noexcept 关键字删掉,不过这样也需要修改 protoc 的源码,保证生成出来的 .pb.h/.pb.cc 中也没有 noexcept

第三种是修改 UBT 源码,加入 /EHsc 标记,这种不推荐

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值