UE4
UnrealEngine4

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])

参考文献