x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Delay Load DLLs causing breakpoint

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!

Product Version: UE 4.11
Tags:
more ▼

asked Apr 08 '16 at 04:34 PM in C++ Programming

avatar image

AgentMilkshake1
275 13 18 33

avatar image AgentMilkshake1 Apr 08 '16 at 04:35 PM

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

(comments are locked)
10|2000 characters needed characters left

1 answer: sort voted first

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!

more ▼

answered Apr 08 '16 at 04:46 PM

avatar image

HazzaBui
71 1 2 10

(comments are locked)
10|2000 characters needed characters left
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question