Has anyone got any experience with attempting to pass a FString to a C# function taking a String?
Currently I am attempting the following:
UE4 code:
typedef void(*_TestCFunction)(FString string);
FString filePath = FPaths::Combine(*FPaths::GamePluginsDir(), TEXT("TestPlugin/"), TEXT("CTestPlugin.dll"));
if (FPaths::FileExists(filePath))
{
void *DLLHandle;
DLLHandle = FPlatformProcess::GetDllHandle(*filePath);
if (DLLHandle != NULL)
{
UE_LOG(LogLevel, Warning, TEXT("dll handle created"));
_TestCFunction DLLFuncPtr = NULL;
FString procName = "TestCFunction";
DLLFuncPtr = (_TestCFunction)FPlatformProcess::GetDllExport(DLLHandle, *procName);
if (DLLFuncPtr != NULL)
{
// InputString is a FString defined prior to this function, but it does exist and does have text in it.
DLLFuncPtr(InputString);
}
}
}
C# code:
[DllExport("TestCFunction", CallingConvention = CallingConvention.StdCall)]
static public void TestCFunction([MarshalAs(UnmanagedType.LPWStr)]String inputstring)
{
// Removed internal debugging but various things do happen here. The first is printing the String out to a log file though before any other interaction with the string
return;
}
There are a couple things to note here for debugging/solving purposes.
In terms of passing the string to the C# function I’ve tried passing *InputString, InputString.GetCharArray(), conversions of utf8, ansi, tchar, etc. They all seem to be corrupted as inside the C# function I print what is received to a debug file and it is not printing the proper string (It never changes in size regardless of the input string and always seems to be some garbage memory). I expect I am maybe just not converting the string to the proper encoding or format but I have yet to figure out which one it should be. Alternatively if that is not the problem I would expect I am simply passing the string incorrectly in general.
For the DLLExport I’ve attempted changing the CallingConvention to Cdecl as well as not using the MarshalAs for the string but neither of those worked either.
Also worth noting is that I have attempted compiling the DLL in both 64bit and 32bit (Although with intentions of using 64bit. 32bit was just for debugging attempts.)
Any ideas, suggestions, or anything of the sort are appreciated.
yes but not c# String, instead use string, the c# string is equivalent to char* in c++ so you need just pass the FString to char* and pass to your function
Thanks for the help ZkarmaKun! I got it functional using string instead of String and passing by char*.
In regards to avoiding using C# this dynamic library is not used for actual gameplay and I didn’t wish to convert the entire thing to C++ but with some small back-and-forth calls could make it fully functional which it now is.
I created the Release x64 bits .dll file with visual studio in the next form:
The result of that building was:
where I copied the content of the path x64/Release to the path <my_UE4_Project>/Plugins/Ejemplo_dll3. The path had the next files:
-Ejemplo_dll3.dll
-Ejemplo_dll3.exp
-Ejemplo_dll3.lib
-Ejemplo_dll3.pdb
Into the Unreal’s blueprint class I wrote the next code:
But the “Return Value” is allways -3.0 because the program generate “DLLgetCircleArea = (_getCircleArea)FPlatformProcess::GetDllExport(DLLHandle, *procName) as a null value”.
POST: anyway as i say before, is c++ you almost dont need export function in c++ to c++, every windows header is allow by unreal, and i recommend use .lib for better results.
It didn’t work. I added the expression __declspec(dllexport) that you recommend me into the .dll file but the error is the same: The code return a Null value for the expresion “(getCircleArea)FPlatformProcess::GetDllExport(DLLHandle, *procName);”
While I do agree with ZkarmaKun in regards to not needing to dllexport the C++ function - in terms of curiosity and getting it functioning you should try using Dependency Walker (http://www.dependencywalker.com/) to see if the function is being properly exported and if it is, what its exact name is. The name of your import in UE4 and the export of the dll must match exactly including capitalization.
mmm seems weird, when you create a new project for build a .dll you must choose win32 application and in the wizard creator also must set DLL instead Console application, its allow you the export with __declspec(dllexport) other way you are doing something wrong!
i hope this help you
Cheers!
EDIT: and Alters in right must use exactly same name
Calling a C# function directly from C++ is impossible. C# functions are written using CIL bytecode and placed inside an assembly which is a file format specific to C# and other .NET languages. Those functions can only be run using a C# runtime like .NET or Mono. While assemblies are normally given .exe or .dll file extensions, they are not the same.
As for what you’re doing now with C++. Instead of trying to manually look up the function for each call, which would slow your function down by several orders of magnitude, you should just reference your DLL’s library and headers directly.
You’ll need to find a tutorial that explains how static or dynamic linking occurs when it comes to C++.
Edit2: Sorry, I read bad the answer given by the software. This is the correct answer that is the same name of the function into de dll project and is the name that I gave to FString procName value which is used in: