以UE5第三方插件库为基础,编写自己的第三方库插件,并且能够在运行时复制.dll
首先,创建一个空白的C++ 项目,创建第三方插件库。如下图所示
编译自己的.Dll 和.lib 库,打开.sln 如下图
ExampleLibrary.h 的代码如下
#if defined _WIN32 || defined _WIN64
#define EXAMPLELIBRARY_IMPORT __declspec(dllimport)
#elif defined __linux__
#define EXAMPLELIBRARY_IMPORT __attribute__((visibility("default")))
#else
#define EXAMPLELIBRARY_IMPORT
#endif
EXAMPLELIBRARY_IMPORT void ExampleLibraryFunction();
EXAMPLELIBRARY_IMPORT int AddNumbersFunction(int a,int b);
ExampleLibrary.cpp 的代码如下
#if defined _WIN32 || defined _WIN64
#include <Windows.h>
#define EXAMPLELIBRARY_EXPORT __declspec(dllexport)
#else
#include <stdio.h>
#include "ExampleLibrary.h"
#endif
#ifndef EXAMPLELIBRARY_EXPORT
#define EXAMPLELIBRARY_EXPORT
#endif
EXAMPLELIBRARY_EXPORT void ExampleLibraryFunction()
{
#if defined _WIN32 || defined _WIN64
MessageBox(NULL, TEXT("Loaded ExampleLibrary.dll from Third Party Plugin sample."), TEXT("Third Party Plugin"), MB_OK);
#else
printf("Loaded ExampleLibrary from Third Party Plugin sample");
#endif
}
EXAMPLELIBRARY_EXPORT int AddNumbersFunction(int a,int b)
{
return a+b;
}
然后编译.Dll 库,配置如下
然后点击生成解决方案,编译成功后,如下图所示
创建蓝图库函数,运行时放在 插件中,如下图所示
要在WlThirdPartyLibrary.Build.cs 添加 “Engine”,“CoreUObject”,否则编译不成功
如下图
在蓝图库函数里面调用.Dll 里面得函MyBlueprintFunctionLibrary.h的代码如下
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyBlueprintFunctionLibrary.generated.h"
/**
*
*/
UCLASS()
class WLTHIRDPARTYLIBRARY_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable,Category="Function")
static int AddNumbers(int a, int b);
};
MyBlueprintFunctionLibrary.cpp 的代码如下
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyBlueprintFunctionLibrary.h"
#include "WlThirdPartyLibraryLibrary/ExampleLibrary.h"
int UMyBlueprintFunctionLibrary::AddNumbers(int a, int b)
{
return AddNumbersFunction(a, b);
}
WlThirdPartyLibraryLibrary.Build.cs 的代码修改比较大,添加了自动复制.dll 的功能,代码如下
// Fill out your copyright notice in the Description page of Project Settings.
using System.IO;
using UnrealBuildTool;
public class WlThirdPartyLibraryLibrary : ModuleRules
{
public WlThirdPartyLibraryLibrary(ReadOnlyTargetRules Target) : base(Target)
{
Type = ModuleType.External;
PublicSystemIncludePaths.Add("$(ModuleDir)/Public");
if (Target.Platform == UnrealTargetPlatform.Win64)
{
// Add the import library
PublicAdditionalLibraries.Add(Path.Combine(ModuleDirectory, "x64", "Release", "ExampleLibrary.lib"));
// Delay-load the DLL, so we can load it from the right place first
PublicDelayLoadDLLs.Add("ExampleLibrary.dll");
// Ensure that the DLL is staged along with the executable
CopyDll(Path.Combine(ModuleDirectory, "x64", "Release", "ExampleLibrary.dll"));
}
else if (Target.Platform == UnrealTargetPlatform.Mac)
{
PublicDelayLoadDLLs.Add(Path.Combine(ModuleDirectory, "Mac", "Release", "libExampleLibrary.dylib"));
RuntimeDependencies.Add("$(PluginDir)/Source/ThirdParty/WlThirdPartyLibraryLibrary/Mac/Release/libExampleLibrary.dylib");
}
else if (Target.Platform == UnrealTargetPlatform.Linux)
{
string ExampleSoPath = Path.Combine("$(PluginDir)", "Binaries", "ThirdParty", "WlThirdPartyLibraryLibrary", "Linux", "x86_64-unknown-linux-gnu", "libExampleLibrary.so");
PublicAdditionalLibraries.Add(ExampleSoPath);
PublicDelayLoadDLLs.Add(ExampleSoPath);
RuntimeDependencies.Add(ExampleSoPath);
}
}
private void CopyDll(string InFilePath)
{
// string TargetDirectory = Path.GetFullPath(Path.Combine(PluginDirectory, "Binaries/ThirdParty", "WlThirdPartyLibraryLibrary", "Win64"));
string TargetDirectory = Path.GetFullPath(Path.Combine(PluginDirectory, "Binaries/ThirdParty/WlThirdPartyLibraryLibrary/Win64"));//目标文件夹的路径
string FileName = Path.GetFileName(InFilePath);//获得文件名字
// Ensure that the DLL is staged along with the executable
if (!Directory.Exists(TargetDirectory))//检查目标文件夹是否存在不存在则创建
{
Directory.CreateDirectory(TargetDirectory);
}
string TargetFilePath = Path.Combine(TargetDirectory, FileName);//目标文件的路径
if (!File.Exists(TargetFilePath))
{
File.Copy(InFilePath, TargetFilePath, true);//复制.dll
}
RuntimeDependencies.Add("$(PluginDir)/Binaries/ThirdParty/WlThirdPartyLibraryLibrary/Win64/ExampleLibrary.dll");//运行时添加DLL
}
}
还有最后一步,添加白名单WlThirdPartyLibrary.uplugin 的代码如下
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.0",
"FriendlyName": "WlThirdPartyLibrary",
"Description": "",
"Category": "Other",
"CreatedBy": "",
"CreatedByURL": "",
"DocsURL": "",
"MarketplaceURL": "",
"SupportURL": "",
"CanContainContent": true,
"IsBetaVersion": false,
"IsExperimentalVersion": false,
"Installed": false,
"Modules": [
{
"Name": "WlThirdPartyLibrary",
"Type": "Runtime",
"LoadingPhase": "Default",
"WhitelistPlatforms": ["Win64"]
}
]
}