夜雨聆风学习资料网

ARTICLE · 1125281

在 UE4 插件中集成并调用第三方库

在 UE4 插件中集成并调用第三方库

在 UE4 开发中,集成第三方库(如物理引擎、音频处理库、网络库等)是常见的需求。UE4 提供了完善的插件机制,通过创建自定义插件,可以优雅地将第三方库封装并暴露给项目使用。本文将系统讲解整个流程,并给出可运行的代码示例。


一、整体思路

UE4 插件调用第三方库的核心步骤:

  1. 创建插件目录结构
  2. 放置第三方库(源码 / 静态库 / 动态库)
  3. 编写 .Build.cs 配置库路径与链接
  4. 在 Public 中声明接口
  5. 在 Private 中实现调用
  6. 注册插件并在项目中使用

⚠️ 注意:UE4 插件的构建配置使用 C# 编写的 .Build.cs 文件,而不是 Gradle(Gradle 是 Android 或某些自定义构建系统使用的)。原文中提到的 PluginBuild.gradle 是误解,正确文件是 *.Build.cs。


二、创建插件目录

在项目根目录下创建:

MyProject/
└── Plugins/
    └── MyThirdPartyPlugin/
        ├── MyThirdPartyPlugin.uplugin
        ├── Source/
        │   └── MyThirdPartyPlugin/
        │       ├── MyThirdPartyPlugin.Build.cs
        │       ├── Public/
        │       │   └── MyThirdPartyPlugin.h
        │       └── Private/
        │           ├── MyThirdPartyPlugin.cpp
        │           └── ThirdParty/
        │               ├── include/
        │               │   └── MyLib.h
        │               └── lib/
        │                   └── Win64/MyLib.lib
        └── Resources/

MyThirdPartyPlugin.uplugin

{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.0",
"FriendlyName": "My Third Party Plugin",
"Description": "Integrates MyLib into UE4",
"Category": "Other",
"CreatedBy": "YourName",
"CanContainContent": true,
"Modules": [
        {
"Name": "MyThirdPartyPlugin",
"Type": "Runtime",
"LoadingPhase": "Default"
        }
    ]
}

三、配置第三方库(.Build.cs)

假设第三方库是一个静态库 MyLib.lib,头文件在 include/,库在 lib/Win64/。

MyThirdPartyPlugin.Build.cs

using UnrealBuildTool;
using System.IO;

publicclassMyThirdPartyPlugin : ModuleRules
{
publicMyThirdPartyPlugin(ReadOnlyTargetRules Target) : base(Target)
    {
        PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;

        PublicDependencyModuleNames.AddRange(newstring[]
        {
"Core",
"CoreUObject",
"Engine"
        });

// 第三方库根目录
string ThirdPartyPath = Path.Combine(ModuleDirectory, "Private", "ThirdParty");

// 头文件路径
        PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "include"));

// 链接库
if (Target.Platform == UnrealTargetPlatform.Win64)
        {
string LibPath = Path.Combine(ThirdPartyPath, "lib", "Win64");
            PublicAdditionalLibraries.Add(Path.Combine(LibPath, "MyLib.lib"));
        }
elseif (Target.Platform == UnrealTargetPlatform.Linux)
        {
string LibPath = Path.Combine(ThirdPartyPath, "lib", "Linux");
            PublicAdditionalLibraries.Add(Path.Combine(LibPath, "libMyLib.a"));
        }

// 如果是动态库,需要拷贝并延迟加载
// string DllPath = Path.Combine(LibPath, "MyLib.dll");
// RuntimeDependencies.Add("$(BinaryOutputDir)/MyLib.dll", DllPath);
// PublicDelayLoadDLLs.Add("MyLib.dll");
    }
}

四、声明接口(Public 头文件)

Public/MyThirdPartyPlugin.h

#pragma once

#include"CoreMinimal.h"
#include"Modules/ModuleManager.h"

// 对外暴露的接口类
classMYTHIRDPARTYPLUGIN_APIFMyThirdPartyPlugin
{

public:
static FMyThirdPartyPlugin& Get();

/** 调用第三方库的加法函数 */
int32 AddNumbers(int32 A, int32 B);

/** 调用第三方库的字符串处理函数 */
FString ToUpper(const FString& Input);

private:
    FMyThirdPartyPlugin() = default;
};

// 模块定义(可选,供引擎加载使用)
classFMyThirdPartyPluginModule :public IModuleInterface
{
public:
virtualvoidStartupModule()override;
virtualvoidShutdownModule()override;
};

五、实现接口(Private 源文件)

Private/MyThirdPartyPlugin.cpp

#include"MyThirdPartyPlugin.h"

// 第三方库的 C 接口头文件
extern"C"
{
#include"MyLib.h"// 假设提供 int mylib_add(int, int); 和 const char* mylib_toupper(const char*);
}

#define LOCTEXT_NAMESPACE "FMyThirdPartyPluginModule"

// ---------------- 单例 ----------------
FMyThirdPartyPlugin& FMyThirdPartyPlugin::Get()
{
static FMyThirdPartyPlugin Instance;
return Instance;
}

// ---------------- 接口实现 ----------------
int32 FMyThirdPartyPlugin::AddNumbers(int32 A, int32 B)
{
// 调用第三方 C 函数
return mylib_add(A, B);
}

FString FMyThirdPartyPlugin::ToUpper(const FString& Input)
{
// FString -> std::string -> C 字符串
std::string StdInput = TCHAR_TO_UTF8(*Input);
constchar* Result = mylib_toupper(StdInput.c_str());
return FString(UTF8_TO_TCHAR(Result));
}

// ---------------- 模块加载 ----------------
voidFMyThirdPartyPluginModule::StartupModule()
{
    UE_LOG(LogTemp, Log, TEXT("MyThirdPartyPlugin module started."));
}

voidFMyThirdPartyPluginModule::ShutdownModule()
{
    UE_LOG(LogTemp, Log, TEXT("MyThirdPartyPlugin module shutdown."));
}

#undef LOCTEXT_NAMESPACE

IMPLEMENT_MODULE(FMyThirdPartyPluginModule, MyThirdPartyPlugin)

假设的第三方头文件 include/MyLib.h

#ifndef MYLIB_H
#define MYLIB_H

#ifdef __cplusplus
extern"C" {
#endif

intmylib_add(int a, int b);
constchar* mylib_toupper(constchar* input);

#ifdef __cplusplus
}
#endif

#endif

六、在项目中启用插件

  1. 打开 UE4 编辑器 → Edit → Plugins → 搜索 MyThirdPartyPlugin → 勾选启用。
  2. 重新生成项目文件(右键 .uproject → Generate Visual Studio project files)。
  3. 编译项目。

七、在游戏代码中调用

在任意 Actor 或 GameMode 中:

#include"MyThirdPartyPlugin.h"

voidAMyActor::BeginPlay()
{
    Super::BeginPlay();

// 获取插件单例
    FMyThirdPartyPlugin& Plugin = FMyThirdPartyPlugin::Get();

    int32 Sum = Plugin.AddNumbers(3, 5);
    FString Upper = Plugin.ToUpper(TEXT("hello ue4"));

    UE_LOG(LogTemp, Log, TEXT("Sum=%d, Upper=%s"), Sum, *Upper);
}

输出:

LogTemp: Sum=8, Upper=HELLO UE4

八、常见问题与调试

问题
原因
解决方案
LNK2019 未解析符号
库未链接或名称不匹配
检查 PublicAdditionalLibraries 路径
头文件找不到
未添加 Include 路径
添加 PublicIncludePaths 或 PrivateIncludePaths
运行时崩溃找不到 DLL
动态库未拷贝
使用 RuntimeDependencies.Add
跨平台失败
缺少平台分支
在 Build.cs 中按 Target.Platform 分别配置
命名冲突
第三方头污染
用 extern "C" 包装,且只在 .cpp 中包含

调试建议

  • 使用 Development Editor 配置,日志更详细。
  • 在 Build.cs 中可加入:
    bEnableExceptions = true;      // 若第三方库抛异常
    bUseRTTI = true;               // 若库使用 RTTI
  • 使用 UE_LOG 打印调用前后状态,定位问题。

九、跨平台与版本管理

跨平台:

if (Target.Platform == UnrealTargetPlatform.Win64) { /* .lib */ }
elseif (Target.Platform == UnrealTargetPlatform.Linux) { /* .a */ }
elseif (Target.Platform == UnrealTargetPlatform.Mac) { /* .dylib */ }
elseif (Target.Platform == UnrealTargetPlatform.Android) { /* .so */ }

版本控制:

  • 将插件源码、第三方头文件、库文件一并纳入 Git。
  • 使用 Git LFS 管理 .lib / .dll / .so 等二进制文件。
  • 在 .gitattributes 中声明:
    *.lib filter=lfs diff=lfs merge=lfs -text
    *.dll filter=lfs diff=lfs merge=lfs -text
    *.so  filter=lfs diff=lfs merge=lfs -text

十、总结

步骤
关键文件
创建插件
*.uplugin
配置库
*.Build.cs
声明接口
Public/*.h
实现调用
Private/*.cpp
注册模块
IMPLEMENT_MODULE
使用
FMyThirdPartyPlugin::Get()

通过上述流程,你可以将任意第三方 C/C++ 库无缝集成进 UE4 项目。核心要点是:

  1. .Build.cs 是唯一构建入口(不是 Gradle);
  2. 头文件隔离,避免污染引擎命名空间;
  3. 按平台分别配置,保证跨平台可编译;
  4. 统一封装接口,游戏逻辑只依赖插件公开 API。

持续维护插件,跟进 UE4/UE5 引擎升级与第三方库版本,可以让你的项目长期稳定获益。

相关学习资料