johnsoncodehk 发表于 2023-2-6 13:56

UE集成protobuf

做个记录,网上找的资料,自己做一遍后回忆码下。
到google下载源码工程
Releases · protocolbuffers/protobuf
CMAKE如下配置,先configure,然后取消 protobuf_MSVC_STATIC_RUNTIME 的勾选,重新configure,再generate,



不取消 protobuf_MSVC_STATIC_RUNTIME 的勾选,UE4项目无法编译通过,会有报错:【 LNK2038 检测到“RuntimeLibrary”的不匹配项: 值“MT_StaticRelease”不匹配值“MD_DynamicRelease”(SharedPCH.Engine.NonOptimized.ShadowErrors.h.obj 中) 】,
因为在UE4项目中,项目配置属性的代码生成的运行库默认为 多线程DLL(/MD),在头文件 yvals.h 中生效的配置为 MD_DynamicRelease,如下图所示:


而在CMake()生成的Protobuf解决方案中,Release解决方案配置导出的lib文件为 MT_StaticRelease,故而导致UE4项目编译不过。
在CMake点击 Generate 生成解决方案后,打开项目(protobuf.sln),解决方案配置必须选Release,选中如下图所示:


④ 双击 out 目录下的 extract_includes.bat 脚本,它会在当前目录生成一个 include 文件夹,作为导入UE4项目的Protobuf库的头文件群,同时,上一个步骤会在 out 目录下生成一个 Release 文件夹,其中包含两个lib文件 libprotobuf.lib 和 libprotoc.lib,还有一个工具 protoc.exe (可以将protoc.exe目录添加到系统Path的环境变量中,方便后续直接cmd命令调用)用于将 .proto 文件生成 .h 和 .cc 源文件,至此,就得到了需要复制到UE4项目中的 include 文件夹和两个lib文件;接下来就是ue的接入第三方库流程,直接上图目录结构,这边起来个插件,名为NetWork
然后include和lib的存放路径如下


然后需要在NetWork.Build.cs中将protobuf的头文件开放出来给外部调用,同时添加运行库,直接上代码。此处不包含移动端,后续需要做移动端再来补充(基本思路就是拷贝protobuf的so文件到android的编译目录,下一篇ue调android蓝牙再补充类似流程)
// Copyright Epic Games, Inc. All Rights Reserved.

using System;
using System.IO;
using System.Reflection;
using UnrealBuildTool;

public class NetWork : ModuleRules
{
        public void AddRange()
        {
      PublicIncludePaths.AddRange(
         new string[] {
               // ... add public include paths required here ...
                Path.Combine(PluginDirectory, "Source/NetWork/ThirdParty/Protobuf/Include/"),
                Path.Combine(PluginDirectory, "Source/NetWork/Public/")
         }
         );


      PrivateIncludePaths.AddRange(
            new string[] {
                                // ... add other private include paths required here ...
            }
            );


      PublicDependencyModuleNames.AddRange(
            new string[]
            {
                "Core",
                "Sockets",
                "Networking"
                                // ... 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 ...
                        }
            );
    }
        public NetWork(ReadOnlyTargetRules Target) : base(Target)
        {
                PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
      // 添加需要设置的宏
      PublicDefinitions.Add("GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE=0");

      string path1 = Path.Combine(PluginDirectory, "Source/NetWork/ThirdParty/Protobuf/Include");
      PublicSystemIncludePaths.Add(path1);

      path1 = Path.Combine(PluginDirectory, "Source/NetWork/ThirdParty/Protobuf/Lib");
      PublicSystemIncludePaths.Add(path1);

      path1 = Path.Combine(PluginDirectory, "Source/NetWork/ThirdParty/Protobuf/Lib/libprotobuf.lib");
      PublicAdditionalLibraries.Add(path1);

                AddRange();

    }
}


注意:
找到拷贝UE的include目录中的protobuf源文件,中打开message_light.h
添加
#pragma warning(disable:4946)
#pragma warning(disable:4800)
不然编译会因为警告报错。

编译proto目录下(.proto)源文件,将编译出来的proto_output(*.pb.cc,*.pb.h)下的文件拷贝到自己工程目录
@echo off
for %%i in (proto_source\*.proto) do protoc -I=proto_source--cpp_out=proto_output%%i
echo success
pause
页: [1]
查看完整版本: UE集成protobuf