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"

Is it possible to call a managed .NET dll from UE4 C++ project?

I have some libraries I've written in C# I'd like to call. Is this possible? Normally I could add the /clr option but since building is all done with custom makefiles I'm not sure how to go about it.

Product Version: Not Selected
Tags:
more ▼

asked Apr 25 '14 at 08:54 AM in C++ Programming

avatar image

tmek
404 30 95 63

avatar image cwm83 Nov 23 '18 at 09:09 PM

I was able to use sameek4's answer to import methods from a custom c# dll that I wrote. My problem now is that the actual code I want to use is in a third party .dll, which I can't modify. I tried to use my custom dll as a wrapper to call methods from the third party dll, but Unreal crashes when I try to access these methods.

I used a simple custom 'third party' dll for testing.

Third Party Dll:

 namespace ThirdPartyTest
 {
     public class ThirdPartyClass
     {
         public int MultiplyByFour(int otherNumber)
         {
             return otherNumber * 4;
         }     
     }    
 }

C# DLLExport Wrapper:

 using RGiesecke.DllExport;
 using System.Runtime.InteropServices;
 using ThirdPartyTest;
 
     namespace DLLExportWrapper {
         public static class WrapperClass
         {                
             [DllExport("ReturnThree", CallingConvention = CallingConvention.StdCall)]
             public static int ReturnThree()
             {
                 return 3;
             }    
             [DllExport("MultiplyByFour", CallingConvention = CallingConvention.StdCall)]
             public static int MultiplyByFour(int otherNumber)
             {
                 ThirdPartyClass thirdPartyClass = new ThirdPartyClass();
                 return thirdPartyClass.MultiplyByFour(otherNumber);    
             }        
         } 
       }

I am able to successfully use the ReturnThree method in Unreal, but the MultiplyByFour causes a crash when I call it. My knowledge of c++/c# is quite limited, so I certainly acknowledge I am in over my head. Is what I want to do possible?

avatar image Shadowriver Nov 24 '18 at 06:55 AM

What is call stack saying? do it crash on directly on your call or does it goes farther. Also what types do you operating in? a int as you showed in example? no.1 reason of hard crashes in invalid memory pointers. can you also show C++ portion? can you say example of library you trying to use?

avatar image cwm83 Nov 24 '18 at 04:26 PM

Here is the c++:

     int UTestFunctions::TestDLLMultiplyByFour(int otherNumber)
     {
         typedef int(*_MultiplyByFour)(int res);
         FString filePath = FPaths::Combine(*FPaths::GamePluginsDir(), TEXT("ThirdParty/CLR_TestLib.dll"));
     
         void *DLLHandle = NULL;
         if (FPaths::FileExists(filePath))
         {
             DLLHandle = FPlatformProcess::GetDllHandle(*filePath); // Retrieve the DLL.
         }
         if (DLLHandle != NULL)
         {
             _MultiplyByFour DLLFuncPtr = NULL;
             FString procName = "MultiplyByFour";
             DLLFuncPtr = (_MultiplyByFour)FPlatformProcess::GetDllExport(DLLHandle, *procName);
             if (DLLFuncPtr != NULL)
             {
                 int result = DLLFuncPtr(otherNumber);
                 return result;
             }
         }
         return 0;
 }
avatar image cwm83 Nov 24 '18 at 04:26 PM

And the start of the crash log:

  CLR exception - code e0434352 (first/second chance not available)
     
 KERNELBASE 
 MSVCR120_CLR0400
  ntdll
  clr
  clr
  clr
  clr 
 UE4Editor_TestPlugin!UTestFunctions::TestDLLMultiplyByFour() [c:\users\morse\documents\unreal projects\myproject2\plugins\testplugin\source\testplugin\public\test1.cpp:58] 
 UE4Editor_TestPlugin!UTestFunctions::execTestDLLMultiplyByFour() [c:\users\morse\documents\unreal projects\myproject2\plugins\testplugin\source\testplugin\public\test1.h:14] 
 UE4Editor_CoreUObject!UFunction::Invoke() [d:\build\++ue4\sync\engine\source\runtime\coreuobject\private\uobject\class.cpp:4861] UE4Editor_CoreUObject!UObject::CallFunction() [d:\build\++ue4\sync\engine\source\runtime\coreuobject\private\uobject\scriptcore.cpp:816] 

The crash logs lists line 58 in my c++, which is the following line:

 int result = DLLFuncPtr(otherNumber);

This same line works when calling a method from the wrapper dll that does not try to call a method from a 'thirdparty' dll.

I started this with the idea of maybe using something from Rhino Inside, which is currently available only as .NET. But to be honest it's really just more of a learning exercise for me, so I'll be happy with just getting my simple test 'third party' dll working.

avatar image Jagveer Singh Jan 11 '19 at 09:12 AM

@cwm83 Are your able to solve this problem. I am also getting the same problem. I am able to call the method which is available in direct dll. But, when i call the method which uses some function from third party dll, it crashes.

I am stuck in this.

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

4 answers: sort voted first

Yes , why not ? I did it. Create a C# library dll project in your UE4 solution and refer its build path to your plugin directory. Then write a function in C# , like this :

  [DllExport("GetDomain", CallingConvention = CallingConvention.StdCall)]
         static public string GetDomainName(bool result)
         {
             System.Security.Principal.WindowsIdentity currentUser = System.Security.Principal.WindowsIdentity.GetCurrent();
             return currentUser.Name.Split('\\')[0];
         }

The above function gives info on your current PC domain. Now build the project , see if a dll is created in your plugin directory.

Then create a BPFunctionlibrary C++ class , and add a function , that can be called in your BP. My function to retrieve domain information is given below :

 FString ULDAPAuthentication::GetCurrentDomain()
 {
     typedef const char*(*_GetDomain)(bool res);
     FString filePath = FPaths::Combine(*FPaths::GamePluginsDir(), TEXT(YourDLLName.dll"));

     void *DLLHandle = NULL;
     if (FPaths::FileExists(filePath))
     {
         DLLHandle = FPlatformProcess::GetDllHandle(*filePath); // Retrieve the DLL.
     }
     if (DLLHandle != NULL)
     {
         _GetDomain DLLFuncPtr = NULL;
         FString procName = "GetDomain";
         DLLFuncPtr = (_GetDomain)FPlatformProcess::GetDllExport(DLLHandle, *procName);
         if (DLLFuncPtr != NULL)
         {
             const char* result = DLLFuncPtr(false);
             FString output(result);
             return output;
         }
     }
     return "";
 }


If the DLLFuncPtr is coming as null , please write a blank function before other functions in yuor C# , like below :

     [DllExport("TestFunction", CallingConvention = CallingConvention.StdCall)]
     static public void TestFunction()
     {
         
     }

because I dont know the reason , but the first function in your C# class in never detected

more ▼

answered Dec 06 '15 at 04:47 AM

avatar image

sameek4
132 37 40 69

avatar image luisibadr Jan 12 '16 at 06:38 AM

Hi! I can see that you're able to use C# dll in Unreal Engine, please could you post a completed example about it, I mean where to créate a C# dll and how to link in C++ to use it..... thanks!

avatar image hardylr May 10 '16 at 12:46 PM

Are you sure your Dll is written in C#? I have tested this method and I cannot get it my to link to the C# method inside my DLL. The function pointer is coming in as null. Tried the blank function workaround and still no success.

Could you please share a completed example or example project? Thanks!

avatar image paranoio Sep 06 '18 at 04:44 AM

this worked for me, i created a dll using C# net framework 4.5 , using RGiesecke.DllExpor, and building for x64 platform

avatar image StamFP Mar 04 '19 at 12:12 PM

Hi could you elaborate a bit more? I cannot seem to get the DLLFuncPtr to not return null...Is there a special setup you need to do with C# or C++ part of things?

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

Hi, I just stumbled over your question, and while I haven't tried it myself, I think https://wiki.unrealengine.com/Linking_Dlls might be of help.

more ▼

answered Mar 26 '15 at 11:27 PM

avatar image

ppetermann
14 2 3 4

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

You cannot directly use C# in your project. I've used a C# dll by using a CLI C++ DLL and then using LoadLibrary and GetProcAddress to load the functions.

That would be my suggestion if you can't just rewrite it in C++.

more ▼

answered Mar 27 '15 at 12:14 AM

avatar image

DevChagrins
11 1

avatar image hardylr May 10 '16 at 12:49 PM

Your answer is in direct contrast to what sameek4 says. Im my research online it does not seem possible to call C# functions from C++ code directly. You need a bridge CLI dll as you mentioned.

Could you please share an example, specifically using the bridge CLI with Unreal? Thanks

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

This topic seems like don't have final answer sammeek4 was right. It's possible to use C# dll with ue4 without using COM or anything like that.Here you've got how to create managed dll with unmanaged export (so u can use it without .net virtual machine). Later u got to paste dll to the project folder. Don't forget to add dll info in your Build.cs file [ i got something like this PublicDelayLoadDLLs.Add("UnmanagedFrameworkDll.dll"); ] After completing this I put following code in my BlueprintFunctionLibrary.cpp

 void *v_csdllHandle;
 
 typedef int(*_MyCsDllLibraryFunction)();
 
 _MyCsDllLibraryFunction m_myCsDllLibraryFunctionHandle;
 
 bool UMyDllBlueprintFunctionLibrary::importCsDLL(FString folder, FString name)//same as no c# version. only the handle changed
 {
     FString filePath = *FPaths::ProjectPluginsDir() + folder + "/" + name;
 
     if (FPaths::FileExists(filePath))
     {
         v_csdllHandle = FPlatformProcess::GetDllHandle(*filePath); // Retrieve the DLL.
         if (v_csdllHandle != NULL)
         {
             return true;
         }
     }
     return false;    // Return an error.
 }
 
 
 bool UMyDllBlueprintFunctionLibrary::LoadMyCSharpDLLFuntion()
 {
     if (v_csdllHandle != NULL)
     {
         m_myCsDllLibraryFunctionHandle = NULL;
         //now u need to pass the exact name of the dll function
         FString procName = "UnmanagedFunction";
         m_myCsDllLibraryFunctionHandle = (_MyCsDllLibraryFunction)FPlatformProcess::GetDllExport(v_csdllHandle, *procName);
         if (m_myCsDllLibraryFunctionHandle != NULL)
         {
             return true;
         }
     }
     return false;
 }
 
 
 int UMyDllBlueprintFunctionLibrary::CallMyCSharpDLLFuntion()
 {
     return m_myCsDllLibraryFunctionHandle();
 }


more ▼

answered May 10 '18 at 12:59 PM

avatar image

S_Q_R
23 1 6 7

(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