UE4_第三方库的引用

UE4中引用第三方库和一般C++项目是有区别的。下面主要介绍lib静态库和dll动态库的引用:
Demo调试工具:UE4.15.3 、VS2015

新建UE4项目

首先在UE4中新建一个空的C++项目,命名为“JNI_Test”,新建一个C++类,继承自BlueprintFunctionLibrary,命名为“LinkDllBFL”,之后在这定义静态全局函数实现第三方库函数的调用。在JNI_Test项目目录下新建两个文件夹Resources和ThirdPart用于存放后文中的两种第三方库。

lib静态链接库的引用

UE4中lib静态库的引用需要依赖UBT(Unreal Building System)系统,所以需要在Build.cs中实现。

创建lib

在VS中创建新Win32项目,命名“LibTest”,程序类型为静态连接库。在解决方案中添加名为“MyLib”的类:
Mylib.h

#pragma once
//通过半径计算面积
float getCircleArea(float radius);

Mylib.cpp

#include "stdafx.h"
#include "MyLib.h"

float getCircleArea(float radius)
{
    return 3.14159265 * (radius * radius);
}

选择x64编译生成解决方案,在项目文件夹中找到x64下的“LibTest.lib”和”MyLib.h”,此处将这两个文件复制到UE4项目“JNI_Test”的“JNI_Test/ThirdPart/x64”目录中。

修改Build.cs

接下来,打开项目C++代码,开始修改Build.cs:

// Fill out your copyright notice in the Description page of Project Settings.

using UnrealBuildTool;
using System;
using System.IO;

public class JNI_Test : ModuleRules
{
    private string ThirdPartPath
    {
        //通过get方法获得ModuleDirectory上两级的ThirdPart目录。
        //ModuleDirectory指的是Build.cs所在的目录
        get
        {
            return Path.GetFullPath(Path.Combine(ModuleDirectory, "../../ThirdPart"));
        }
    }

    //加载lib(此处判断了平台信息,预留了win32的接口)
    private bool LoadThirdPartLib(TargetInfo Target)
    {
        if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Win32))
        {
            string platformStr = Target.Platform == UnrealTargetPlatform.Win64 ? "x64" : "x86";
            //得到lib地址
            string lib_path = Path.Combine(ThirdPartPath, platformStr, "LibTest.lib");

            //添加lib库到includepaths
            PublicAdditionalLibraries.Add(lib_path);
            PrivateIncludePaths.Add(Path.Combine(ThirdPartPath, platformStr));
            PublicIncludePaths.Add(Path.Combine(ThirdPartPath, platformStr));

            return true;
        }
        return false;
    }

    public JNI_Test(TargetInfo Target)
    {
        LoadThirdPartLib(Target);
        PublicIncludePaths.AddRange(new string[] { "JNI_Test/Public" });

        PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });

        PrivateDependencyModuleNames.AddRange(new string[] {  });

        // Uncomment if you are using Slate UI
        // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });

        // Uncomment if you are using online features
        // PrivateDependencyModuleNames.Add("OnlineSubsystem");

        // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
    }
}

修改完成之后静态库的引入就完成了,是不是很简单。接下来在需要使用lib库中函数的头文件中添加#include “MyLib.h”即可调用lib库中的getCircleArea函数了。

库函数调用

LinkDllBFL.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyLib.h"
#include "LinkDllBFL.generated.h"

/**
 * 
 */
UCLASS()
class JNI_TEST_API ULinkDllBFL : public UBlueprintFunctionLibrary
{
    GENERATED_BODY()

public:

    UFUNCTION(BlueprintCallable, Category = "Lib")
    static float circleArea(float radius);

};

LinkDllBFL.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "JNI_Test.h"
#include "LinkDllBFL.h"

//调用lib库中getCircleArea函数
float ULinkDllBFL::circleArea(float radius)
{
    return getCircleArea(radius);
}

生成或者compile编译项目。

蓝图编辑,Play

之后我们在UE4编辑器中创建一个JNI_TestGameModeBase的蓝图类“MyJNI_TestGameModeBase”,在MyJNI_TestGameModeBase中编辑如下:
这里写图片描述
然后点击Play运行项目,运行结果如下:
这里写图片描述

dll动态链接库的引用

动态链接库dll的引用与静态链接库不同,不需要依赖UBT系统,直接在C++代码中动态引入即可。
步骤如下:

创建dll

在VS中创建新Win32项目,命名“DllTest”,程序类型为dll动态连接库。在解决方案中添加名为“MyDllTest”的类:
MyDllTest.h

#pragma once
#define DLL_EXPORT __declspec(dllexport)//定义dll的函数导出接口
#ifdef __cplusplus
extern "C"
{
#endif 
    float DLL_EXPORT getCircleArea(float radius);

#ifdef __cplusplus
}
#endif

MyDllTest.cpp


#include "MyDllTest.h"

float DLL_EXPORT getCircleArea(float radius)
{
    return float(3.14159265 * (radius * radius));
}

依然选择x64编译解决方案DllTest。在DllTest\x64\Debug 中找到生成的“DllTest.dll”文件,复制到UE4项目的JNI_Test\Resources 目录下。
之后开始在UE4项目的C++代码中修改:

修改LinkDllBFL类

LinkDllBFL.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyLib.h"
#include "LinkDllBFL.generated.h"

/**
 * 
 */
UCLASS()
class JNI_TEST_API ULinkDllBFL : public UBlueprintFunctionLibrary
{
    GENERATED_BODY()

public:
    //调用lib库中getCircleArea函数
    UFUNCTION(BlueprintCallable, Category = "Lib")
    static float circleArea(float radius);

    UFUNCTION(BlueprintCallable, Category = "DLL")
    static bool importDLL(FString folder, FString name);

    UFUNCTION(BlueprintCallable, Category = "DLL")
    static bool importMethodGetCircleArea();

    UFUNCTION(BlueprintCallable, Category = "DLL")
    static float getCircleAreaFromDll(float radius);

    UFUNCTION(BlueprintCallable, Category = "DLL")
    static void freeDLL();
};

LinkDllBFL.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "JNI_Test.h"
#include "LinkDllBFL.h"

typedef float(*_getCircleArea)(float radius);//定义一个函数指针来存储dll中的getCircleArea函数原型

_getCircleArea m_getCircleAreaFromDll;

void *dllHandle;

//加载DLL
bool ULinkDllBFL::importDLL(FString folder, FString name)
{
    FString filePath = *FPaths::GameDir() + folder + "/" + name;

    if (FPaths::FileExists(filePath))
    {
        dllHandle = FPlatformProcess::GetDllHandle(*filePath);//得到dll句柄
        if (dllHandle != NULL)
        {
            return true;
        }
    }
    return false;
}

//从DLL中得到函数getCircleArea
bool ULinkDllBFL::importMethodGetCircleArea()
{
    if (dllHandle != NULL)
    {
        m_getCircleAreaFromDll = NULL;
        FString procName = "getCircleArea";
        m_getCircleAreaFromDll = (_getCircleArea)FPlatformProcess::GetDllExport(dllHandle, *procName);
        if (m_getCircleAreaFromDll != NULL)
        {
            return true;
        }
    }
    return false;
}

//调用从DLL中传入的getCircleArea函数
float ULinkDllBFL::getCircleAreaFromDll(float radius)
{
    if (m_getCircleAreaFromDll != NULL)
    {
        float out = float(m_getCircleAreaFromDll(radius));//调用dll函数
        return out;
    }
    return -32202.0f;//返回错误
}

//卸载DLL
void ULinkDllBFL::freeDLL()
{
    if (dllHandle != NULL)
    {
        m_getCircleAreaFromDll = NULL;      
        FPlatformProcess::FreeDllHandle(dllHandle);
        dllHandle = NULL;
    }
}

float ULinkDllBFL::circleArea(float radius)
{
    return getCircleArea(radius);
}

此处我们在LinkDllBFL中实现了4个静态全局函数,分别实现了加载dll、得到dll函数、调用dll函数、卸载dll的功能,之后我们还是来到UE4编辑器中用蓝图实现函数的调用。

蓝图编辑,Play

这里写图片描述
编译保存之后,Play!!
得到了和上文lib相同的结果:
这里写图片描述

参考文章:
https://wiki.unrealengine.com/Linking_Static_Libraries_Using_The_Build_System
https://wiki.unrealengine.com/Linking_Dlls

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值