版权声明:作者qq:3689852,转载请保留版权 https://blog.csdn.net/qq_36409711/article/details/82112867
前段时间在研究UE4引入外部的函数库,但是由于网上的相关文章并不多,大都东拼西凑,或者故意写的很花哨,不利于新手学习,或者直接无脑的转载,比如各种感谢A先生……,很多文章我都照着做了但都未成功,我都怀疑那些发布文章的大佬自己有没有链接成功,上文和下文明显驴唇不对马嘴,最起码把函数名字改成一样的吧,明显都是东拼西凑的一片文章,拿出来发布,赚点人气。
不过也有一些大佬的文章确实写的不错,慷慨解囊,小编在这里向这些行业里无私奉献,对我们新手不厌其烦的解答的那些大佬深深鞠躬
好了废话不多说了
首先要知道C++引入和UE4引入第三方库是不一样的
C++只需要一行代码就可以
#pragma comment(lib, "mylib.lib")
UE4也可以自己写,不过需要额外的配置,比较麻烦,引擎为了解决这些繁琐的东西,就用C#去管理了
既然要链接第三方库我们就要有第三方库,
如何创建我这里就不多说了,
大家可以看我之前写过的一篇文章
C++dll、lib的定义以及引用
需要注意的是,我们创建的第三方库是分64位 和 32位的
本教程使用64位作为演示
然后我们UE4创建一个空的C++项目,取消初学者选项
在项目的根目录创建ThirdParty文件夹
并创建两个子文件夹
分别是include和lib
存放我们的lib文件和.h文件
打开项目的 Bulid.cs 文件
填写如下代码
// Fill out your copyright notice in the Description page of Project Settings.
using UnrealBuildTool;
using System.IO;
public class UseLib : ModuleRules
{
private string ModulePath
{
get
{
return ModuleDirectory;
}
}
private string ThirdPartyPath
{
get
{
return Path.GetFullPath(Path.Combine(ModulePath, "../../ThirdParty"));
}
}
public UseLib(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
PrivateDependencyModuleNames.AddRange(new string[] { });
PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "include"));
PublicAdditionalLibraries.Add(Path.Combine(ThirdPartyPath,"lib","Mylib.lib"));
PublicAdditionalLibraries.Add(Path.Combine(ThirdPartyPath,"lib","MylibTest.lib"));
}
}
剩下的就是在我们需要的地方直接引入头文件就可以了
#include "../../ThirdParty/inlcude/MyLibClass.h"
float AUseLibActor::GetArea(float r)
{
Round *pRound = new Round();
return pRound->getCircleArea(r);
}
如果有移植需求的话可以写到插件里
方法一样,
也可以创建一个模板,在项目的bulid.cs里添加就好了
上面是引入lib文件的方法,接下来讲解如何在UE4中引入动态链接库dll,动态链接库会比较简单一些,它的特点就是可以动态的增加和删除,
首先我们创建一个DLL文件,
打开VS创建一个Windows控制台应用程序
64位,配置类型.dll
创建一个MyDllTest.cpp的类
编写如下代码
//.h
#pragma once
#define DLL_EXPORT __declspec(dllexport)
#ifdef __cplusplus
extern "C"
{
#endif
float DLL_EXPORT getCircleArea(float radius);
#ifdef __cplusplus
}
#endif
//.cpp
#include "MyDllTest.h"
float DLL_EXPORT getCircleArea(float radius)
{
return (3.14 * (radius * radius));
}
然后F7编译出来,在项目的 x64 文件夹里拿到我们的dll文件
在UE4目录下创建一个新的文件夹,名字随便,我这里用的”DLL”
将我们的dll文件放入到这个文件夹
打开UE4创建一个C++类,选择BlueprintFunctionLibrary作为其父类
编写代码如下
//.h
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyBlueprintFunctionLibrary.generated.h"
/**
*
*/
UCLASS()
class USEDLL_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category = "Chihiri Library")
static float getCircleArea(float radius);
};
//.cpp
#include "MyBlueprintFunctionLibrary.h"
#include "Runtime/Core/Public/Misc/Paths.h"
#include "Engine.h"
typedef float(*_getCircleArea)(float radius);
float UMyBlueprintFunctionLibrary::getCircleArea(float radius)
{
FString filePath = FPaths::Combine(*FPaths::GameDir(), TEXT("DLL/"), TEXT("DllTest.dll")); // Concatenate the plugins folder and the DLL file.
if (FPaths::FileExists(filePath)) //Can the file be found?
{
void *DLLHandle;
DLLHandle = FPlatformProcess::GetDllHandle(*filePath);
if (DLLHandle != NULL)
{
_getCircleArea DLLgetCircleArea = NULL;
FString procName = "getCircleArea"; //The name of the function defined in the DLL
DLLgetCircleArea = (_getCircleArea)FPlatformProcess::GetDllExport(DLLHandle, *procName); // Export the DLL function.
if (DLLgetCircleArea != NULL)
{
float out = DLLgetCircleArea(radius); // Call the DLL function, with arguments corresponding to the signature and return type of the function.
return out; // return to UE
}
}
}
else
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Green, TEXT("Dll file not found !!!"));
}
return 1.00f;
}
然后编译一把,在ue4项目的蓝图中就能找到我们的函数了