Can I load third party DLL in Runtime engine Plugin?

I’ve created engine plugin where I load third party DLL, I want to use this plugin in standalone game.
As per documentation, I need to use “Runtime” type plugin in order to use it in standalone game.
But when I try to package it, while building source code it gives me below mentioned linker error.

LogPlayLevel: UnrealBuildTool: UELinkerFixups.cpp.obj : error LNK2019: unresolved external symbol “void __cdecl EmptyLinkFunctionForStaticInitializationMyPlugin2(void)” (?EmptyLinkFunctionForStaticInitializationMyPlugin2@@YAXXZ) referenced in function “void __cdecl UELinkerFixups(void)” (?UELinkerFixups@@YAXXZ)

If I changed plugin type to “Developer” then it build successfully. But Deveoper plugin does not get included while packaging the game.

So please guide me to solve this issue.

I meant engine plugin type is “Runtime” and plugin loads third party DLL.

Can you show us your ROOT/Plugins/YourPluginName/Source/YourPluginName.Build.cs ? :slight_smile:

Oh wait, I remember now. I had the same issue and I found my answer here. Maybe you have the same issue (copy/paste issue haha :D…).

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

using UnrealBuildTool;
using System.IO;
public class MyPlugin2 : ModuleRules
{
public MyPlugin2(TargetInfo Target)
{

	PublicIncludePaths.AddRange(
		new string[] {
			"Runtime/MyPlugin2/Source/MyPlugin2/Public"
        }
		);
			
	
	PrivateIncludePaths.AddRange(
		new string[] {
			"Runtime/MyPlugin2/Source/MyPlugin2/Private"
		}
		);
		
	
	PublicDependencyModuleNames.AddRange(
		new string[]
		{
			"Core", "CoreUObject", "Engine", "InputCore", "UMG", "Slate", "SlateCore", "RHI", "RenderCore", "Projects"
			// ... add other public dependencies that you statically link with here ...
		}
		);
		
	
	PrivateDependencyModuleNames.AddRange(
		new string[]
		{
			// ... add private dependencies that you statically link with here ...	
		}
		);
	
	
	DynamicallyLoadedModuleNames.AddRange(
		new string[]
		{
			// ... add any modules that your module loads dynamically here ...
		}
		);

    
    var path = Path.GetFullPath(Path.Combine(ModulePath, "../../"));
    PublicIncludePaths.Add(Path.Combine(path, "mylib", "include"));

    PublicDelayLoadDLLs.Add("mylib.dll");
    PublicAdditionalLibraries.Add(Path.Combine(path, "mylib", "libs", "mylib.dll.lib"));
}

private string ModulePath
{
    get { return ModuleDirectory; }
}

}

No, above solution is not applicable for my problem.

Can you show me the file where you have the IMPLEMENT_MODULE macro declared ?

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

#include “IMyPlugin2.h”
#include “myplugin.h”

#define LOCTEXT_NAMESPACE “FMyPlugin2Module”

class FMyPlugin2Module : public IMyPlugin2
{
public:

/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;

};

IMPLEMENT_MODULE(FMyPlugin2Module, MyPlugin2)

void FMyPlugin2Module::StartupModule()
{
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
openDLL();
}

void FMyPlugin2Module::ShutdownModule()
{
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
// we call this function before unloading the module.

}

#undef LOCTEXT_NAMESPACE

First of all, I dont’ see any dll export macro in your class definition. I think it could cause the issue as well, try:

// Change
class FMyPlugin2Module : public IMyPlugin2
// with
class YOUR_PLUGIN_NAME_IN_CAPS_API ClassName
// Example
class FMYPLUGIN2MODULE_API FMyPlugin2Module

Take a look at one of my plugin:

Header

#pragma once
 
#include "ModuleManager.h"

class CLASSICRANGE_API ClassicRangeImpl : public IModuleInterface
{
public:
	/** IModuleInterface implementation */
	void StartupModule();
	void ShutdownModule();
};

CPP:

#include "ClassicRange.h"

void ClassicRangeImpl::StartupModule()
{
}

void ClassicRangeImpl::ShutdownModule()
{
}
 
IMPLEMENT_MODULE(ClassicRangeImpl, ClassicRange)

Found this by the way, maybe it can help