UE4のカスタムプラグイン作成時におけるThirdPartyライブラリの取り込み方

More than 1 year has passed since last update.

検証環境:UE4.18.0


Tl;Dr


  • [PluginName].Build.csに読み込みたいThirdPartyライブラリの名前を指定する


    • Engine側のSource/ThirdPartyに入っているものはBuild.csとtpsがあるので名前だけでOK



  • ヘッダファイル側ならPublicDependencyModuleNames、ソース側ならPrivateDependencyModuleNamesへ


    • (使い分けはこれで合ってるはず)




導入例

今回は例としてopenssl/hmac.hを使いたい場合について説明する


[PluginName].Build.csにライブラリ名を追加する

今回はcpp側でIncludeする予定なので、PrivateDependencyModuleNamesOpenSSLを追加する


  • OpenSSLはEngine側のSource/ThirdPartyにBuild.csとtpsがあるので、ライブラリ名だけの指定でOK


    • Source/ThirdPartyの中にあるフォルダ名=ライブラリ名



  • Plugin内にThirdPartyライブラリを自前で持つ場合は、Build.csとtpsを別途作成し、ライブラリフォルダ(Build.csのある場所)への相対パスを指定する必要がある?(未検証)


[PluginName].Build.cs

// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;

public class [PluginName] : ModuleRules
{
public [PluginName](ReadOnlyTargetRules Target) : base(Target)
{

PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;

// プラグイン本体のヘッダのパス
PublicIncludePaths.AddRange(
new string[] {
"[PluginName]/Public"
// ... add public include paths required here ...
}
);

// プラグイン本体のソース(.cpp)のパス
PrivateIncludePaths.AddRange(
new string[] {
"[PluginName]/Private",
// ... add other private include paths required here ...
}
);

// プラグインのヘッダ内でincludeするやつのパス
PublicDependencyModuleNames.AddRange(
new string[]
{
"Core",
// ... add other public dependencies that you statically link with here ...
}
);

// プラグインのソース内でIncludeするやつのパス
PrivateDependencyModuleNames.AddRange(
new string[]
{
"Projects",
"InputCore",
"UnrealEd",
"LevelEditor",
"CoreUObject",
"Engine",
"Slate",
"SlateCore",
// ... add private dependencies that you statically link with here ...
"OpenSSL", // <= 今回はこれを追加。cpp側でincludeする
}
);

DynamicallyLoadedModuleNames.AddRange(
new string[]
{
// ... add any modules that your module loads dynamically here ...
}
);
}
}



ソース側でIncludeする

VisualStudioなどのIDEを使用している場合、書き方によっては未定義エラーが起きるが、呼び出し方があっていればビルドは通る

(型違いなどのエラーがあればビルドは通りません)


Private/[PluginName].cpp


// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

#include "SHATool.h"
#include "SHAToolStyle.h"
#include "SHAToolCommands.h"
#include "LevelEditor.h"
#include "Widgets/Docking/SDockTab.h"
#include "Widgets/Layout/SBox.h"
#include "Widgets/Text/STextBlock.h"
#include "Widgets/Input/SButton.h"
#include "Framework/MultiBox/MultiBoxBuilder.h"
#include "Base64.h"
#include "string"

// 読み込みたいヘッダファイルを追加
//vvvvvvvvvvvvvvvvvv

#define UI UI_ST
THIRD_PARTY_INCLUDES_START
#include "openssl/hmac.h"
THIRD_PARTY_INCLUDES_END
#undef UI

// ^^^^^^^^^^^^^^^^^^^^^
// ※諸事情によりdefineで囲っている(エラーが出ないやつなら不要)

static const FName [PluginName]TabName("[PluginName]");

#define LOCTEXT_NAMESPACE "F[PluginName]Module"

// ======================== 省略 ========================

FReply F[PluginName]Module::OnClickButton() {

char data[] = "xxxx-xxxx-xxxx-xxxx-xxxx";
char key[] = "xxxx-xxxx-xxxx-xxxx-xxxx";

UE_LOG(LogTemp, Log, TEXT("Clicked"));

unsigned char* result;
unsigned int len = 32;

result = (unsigned char*)malloc(sizeof(char) * len);

// メソッド内で使う
// VisualStudioなどのIDEを使用していると未定義扱いのマークが付く(赤下線)が
// ビルドは通るのでOK
// ※静的解析で型エラーとか起こしてる場合はビルドは通りません
HMAC_CTX ctx;
HMAC_CTX_init(&ctx);

HMAC_Init_ex(&ctx, key, strlen(key), EVP_sha256(), NULL);
HMAC_Update(&ctx, (unsigned char*)&data, strlen(data));
HMAC_Final(&ctx, result, &len);

TArray<uint8> resultArr;
resultArr.Append(result, len);

FString output = FBase64::Encode(resultArr);

free(result);

return FReply::Handled();
}

#undef LOCTEXT_NAMESPACE

IMPLEMENT_MODULE(F[PluginName]Module, [PluginName])



参考文献