About use dll file in plugin. EXE can't find dll

I build a dll file in Visual Studio. effect is very simple, just for test.
so… I create a new plugin in UE4.26

<*.Build.cs> like this:
PublicDelayLoadDLLs.Add(Path.Combine(“file path”, “dll name”));
RuntimeDependencies.Add(Path.Combine(“file path”, “dll name”), StagedFileType.NonUFS);

it’s work! in editor.
now I build windows package.
packaging success.

I see that file:
WindowsNoEditor&lt;project name>\Plugins… xxxx.dll
export finished

but if run EXE, will “Unable to locate program input point in xxxxxxxxxx”
if copy dll file to exe directory or “C:\Windows\System32”, It’s OK.

so…
What’s missing in *.build.cs ?
or
What else anything else ?

I’d also try to put dll in the same directory as executable, but not sure that it will help

it’s work.
just I want to auto complete.

I even do this:
in *.build.cs

File.Copy(“plugin dll file”, “project->Binaries\Win64”, true); //plugin file copy to <Binaries\Win64>
RuntimeDependencies.Add(“project->Binaries\Win64”, StagedFileType.SystemNonUFS); // will copy to <WindowsNoEditor est\Binaries\Win64> in packaging complete

but, the file is locked or in use by another process.

ERROR: Unable to instantiate module ‘MyPlugin’: System.IO.IOException: file “D:\bfdata\mydev\TestPlugin\Plugins\MyPlugin../…/Binaries/Win64\UEModel.dll”

OK, I get it.
If create new plugin have “Third Party Library”

I just don’t understand, Why have two plugin module.

I’ve been trying before combine

I can install my dlls correctly (editor and packaged) using


RuntimeDependencies.Add("$(BinaryOutputDir)/mylibrary.dll", Path.Combine(librariesPath, "mylibrary.dll"));

1 Like

This is the only solution that worked after trying for hours to solve UE not find the dll’s I am using with my plugin

I spent hours on this part and I want to share my solution with you.

  1. Open your plugin’s Build.cs file.
  2. Take an example from my code below.
  3. Correct the names and path according to your own project.

NVMLManagerLibrary.Build.cs (this is an external module)

using System.IO;
using UnrealBuildTool;

public class NVMLManagerLibrary : ModuleRules
{
	public NVMLManagerLibrary(ReadOnlyTargetRules Target) : base(Target)
	{
		Type = ModuleType.External;

        if (Target.Platform == UnrealTargetPlatform.Win64)
		{
            // Add any include paths for the plugin
            PublicIncludePaths.Add(Path.Combine(ModuleDirectory));

            // Add any import libraries or static libraries
            PublicAdditionalLibraries.Add(Path.Combine(ModuleDirectory, "x64", "Release", "NVMLManagerLibrary.lib"));

            // Delay-load the DLL, so we can load it from the right place first
            PublicDelayLoadDLLs.Add("NVMLManagerLibrary.dll");

            string sourcePath = "$(ProjectDir)/Plugins/DryreLUIEssentialsPlugin/Source/ThirdParty/NVML/NVMLManagerLibrary/x64/Release/NVMLManagerLibrary.dll";
            string destinationPath = "$(ProjectDir)/Binaries/Win64/NVMLManagerLibrary.dll";
            string buildPath = "$(BinaryOutputDir)/NVMLManagerLibrary.dll";
            
            // Copy DLL to Binaries Folder
            if (Target.Type == TargetType.Editor)
            {
	            RuntimeDependencies.Add(destinationPath,sourcePath); // For Editor
	            
	            // Plugin Directory
	            //string destinationPath = "$(ProjectDir)/Plugins/DryreLUIEssentialsPlugin/Binaries/ThirdParty/NVMLManagerLibrary/Win64/NVMLManagerLibrary.dll";
            }
            
            // Copy config file to shipped folder
            if (Target.Type == TargetRules.TargetType.Game)
            {
	            RuntimeDependencies.Add(buildPath, sourcePath); // For Build
            }
        }
    }
}

RuntimeDependencies is required for Third Party Library. I created two target type, one for editor and the other one is for game build. This method is worked for me.

Since my module is external, I have to add this into main plugin Build.cs file, PublicDependencyModuleNames.AddRange() inside or PrivateDependencyModuleNames.AddRange(). Module name is “NVMLManagerLibrary” so I added this one.

Example:
image

Also I would like to show you how to DelayLoad your plugin when project launchs.

YourPluginName.h

// Copyright © 2024 - DryreL Design

#include "Modules/ModuleManager.h"
#include "DryreLUIEssentialsBPLibrary.h"
#include "Interfaces/IPluginManager.h"
#include "Misc/Paths.h"
#include "../../ThirdParty/NVML/NVMLManagerLibrary/NVMLManager.h"
#include "../../ThirdParty/ADL/ADLManagerLibrary/ADLManager.h"

#pragma once

class FDryreLUIEssentialsPluginModule : public IModuleInterface
{
public:

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

private:
	/** Handle to the test dll we will load */
	void*	LibraryHandle;
};

YourPluginName.cpp

// Copyright © 2024 - DryreL Design

#include "DryreLUIEssentials.h"

#define LOCTEXT_NAMESPACE "FDryreLUIEssentialsPluginModule"

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

	// Get the base directory of this plugin
	// Get a reference to the plugin manager
	FString myPluginDir = IPluginManager::Get().FindPlugin("DryreLUIEssentialsPlugin")->GetBaseDir();
	FString myprojectDir = FPaths::ProjectDir();
	
	// DEVELOPER NOTE: Make sure to LibraryHande DLLs are in the Binaries folder!
	
	if(IsRHIDeviceNVIDIA())
	{
		// Add on the relative location of the third party dll and load it
		FString LibraryPathNVML;
#if PLATFORM_WINDOWS
		LibraryPathNVML = FPaths::Combine(*myprojectDir, TEXT("/Binaries/Win64/NVMLManagerLibrary.dll"));
#endif // PLATFORM_WINDOWS

		LibraryHandle = !LibraryPathNVML.IsEmpty() ? FPlatformProcess::GetDllHandle(*LibraryPathNVML) : nullptr;
	}
	else if(IsRHIDeviceAMD())
	{
		FString LibraryPathADL;
#if PLATFORM_WINDOWS
		LibraryPathADL = FPaths::Combine(*myprojectDir, TEXT("/Binaries/Win64/ADLManagerLibrary.dll"));
#endif // PLATFORM_WINDOWS
		LibraryHandle = !LibraryPathADL.IsEmpty() ? FPlatformProcess::GetDllHandle(*LibraryPathADL) : nullptr;
	}

	if (LibraryHandle)
	{
		if(IsRHIDeviceNVIDIA())
		{
			nvGPUInitializeNVML();
		}
		else if(IsRHIDeviceAMD())
		{
			adlInitializeADL();
		}
		else if(IsRHIDeviceIntel())
		{
			// Initialize Intel
		}
		else if(IsRHIDeviceApple())
		{
			// Initialize Apple
		}
		else
		{
			// Initialize Other Brand
		}
	}
	else
	{
		FMessageDialog::Open(EAppMsgType::Ok, LOCTEXT("DryreLUIEssentialsError", "Failed to load Third Party library"));
	}
}

void FDryreLUIEssentialsPluginModule::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.

	if(IsRHIDeviceNVIDIA())
	{
		nvGPUShutdownNVML();
	}
	else if(IsRHIDeviceAMD())
	{
		adlGPUShutdownADL();
	}
	else if(IsRHIDeviceIntel())
	{
		// Shutdown Intel

	}
	else if(IsRHIDeviceApple())
	{
		// Shutdown Apple

	}
	else
	{
		// Shutdown Other Brand

	}

	// Free the dll handle
	FPlatformProcess::FreeDllHandle(LibraryHandle);
	LibraryHandle = nullptr;
}

#undef LOCTEXT_NAMESPACE
	
IMPLEMENT_MODULE(FDryreLUIEssentialsPluginModule, DryreLUIEssentialsPlugin)

Hope this helps! Modify the references and paths according to your plugin.
Also you can remove RHI if statements, it was required for my plugin but probably you don’t need it.

1 Like

And after that , how do you call the elements of this third party library ? An example with #includes ?

You will include the header file. In this way, you can access the functions of the 3rd party library while developing the plugin.

However, in order for it to work in the engine and game, you need to load this library with the DelayLoadDLLs function (*.Build.cs).

→ Additionally, when the game build is packaged, this DLL file must be present next to the .exe file for the game to run properly.

1 Like