Delay Load DLLs causing breakpoint

Hi AgentMilkshake1,

Adding the DLL to PublicDelayLoadDlls is only part of the solution - the engine needs to know where the DLL lives, so it can find it once it is required. This can be achieved in a few ways.

The first, and easiest (but least scalable) is to simply copy the DLL to the binary folder of your game/the engine. Binaries will automatically look in their launch directory for DLLs, so generally this should solve the problem.

The next solution is to manually add the DLL folder location to the DLLSearchPath in FPlatformProcess prior to requiring the DLL. This informs the engine where the DLL will be located, so it can be loaded dynamically when needed.

Unfortunately, this approach appears to have been broken in 4.11 (the engine will fail to find the DLL, despite having the full path made available).
To remedy this 4.11 issue, you can manually load the DLL directly, so it will be available when it is required. This isn’t ideal, because it means the overhead of loading the library exists, regardless of whether you actually try to use

it.

Anyway, here’s the code solution. This is written on the assumption that you are loading the DLL inside a plugin (engine or project plugin, should work with both). It should be fairly easy to rework this for plugins included in the

project.

void FPluginModule::StartupModule()
{
	//Search project plugins folder for Dll
	FString dllName = "DllName.dll";
	if (SearchForDllPath(FPaths::GamePluginsDir(), dllName))
	{
	}
	else if (SearchForDllPath(FPaths::EnginePluginsDir(), dllName)) //Failed in project dir, try engine plugins dir
	{
	}
	else
	{
		//Stop loading - plugin required DLL to load successfully
		checkf(false, TEXT("Failed to load dll"));
	}
}

bool FPluginModule::SearchForDllPath(FString _searchBase, FString _dllName)
{
	//Search Plugins folder for an instance of Dll.dll, and add to platform search path
	TArray<FString> directoriesToSkip;
	IPlatformFile &PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
	FLocalTimestampDirectoryVisitor Visitor(PlatformFile, directoriesToSkip, directoriesToSkip, false);
	PlatformFile.IterateDirectory(*_searchBase, Visitor);

	for (TMap<FString, FDateTime>::TIterator TimestampIt(Visitor.FileTimes); TimestampIt; ++TimestampIt)
	{
		const FString file = TimestampIt.Key();
		const FString filePath = FPaths::GetPath(file);
		const FString fileName = FPaths::GetCleanFilename(file);
		if (fileName.Compare(_dllName) == 0)
		{
			FPlatformProcess::AddDllDirectory(*filePath); // only load dll when needed for use. Broken with 4.11.
			FPlatformProcess::GetDllHandle(*file); // auto-load dll with plugin - needed as 4.11 breaks above line.
			return true;
		}
	}
	return false;
}

A final note, if this DLL is part of the game, rather than just editor, and you want it to be packaged in with your game for release, the following line in your build.cs should automatically stage the DLL for distribution (replace

PathToDLL with DLL path, relative to build.cs file location):

RuntimeDependencies.Add(new RuntimeDependency(PathToDLL));

Hope this helps!

Hi all,

I’ve been working on a plugin for a long time, and recently decided to integrate some of the plugin’s third party functionality via their provided .dll and .lib.

I believe I have implemented it correctly as the project with the plugin opens correctly. However, upon clicking a slate UI button I created (which calls a function) the project crashes.

It is crashing on a call to a function within the external library, specifically in a windows lib delayhlp.cpp - specifically made for delay loading dlls.

 using System.IO;
 using UnrealBuildTool;
 
 public class ThirdParty_SDK : ModuleRules
         {
            public ThirdParty_SDK(TargetInfo Target)
             {
                 Type = ModuleType.External;
         
                 // Add the import library.
                 PublicLibraryPaths.Add(Path.Combine(ModuleDirectory, "lib"));
                 PublicAdditionalLibraries.Add("ThirdParty_SDK.lib");
         
                 // Delay-load the DLL.
                 PublicDelayLoadDLLs.Add("ThirdParty_SDK.dll");
             }
         
         }

This module is then included in the main plugin’s build.cs in PublicDependencyModuleNames.

As I said above, I believe that these have been included correctly as previously I was getting a message upon load telling me that the main module had not been created properly.

The specific line that crashes in delayhlp.ccp is line 323

// If we get to here, we blindly assume that the handler of the exception
                 // has magically fixed everything up and left the function pointer in 
                 // dli.pfnCur.
                 //
                 return dli.pfnCur;

Any help would be greatly appreciated, I have a client waiting upon this so the sooner the better.

Thank you in advance!

@VBarata I think my friend is going to post the solution on here, I just deleted the old post.

Did you sovled this problem?

This plugin can solve that problem.

The point is change StartupModule() function.

Hi, could you tell me how to solve this?