I am trying to make MS-SQL integration in UE4 , with C# dll import , and the result is quite impressive , however I am stuck at passing array from C++ to C# , it is throwing unhandled exception. Kindly let me know what are the best ways to pass dynamic string arrays from C++ to C#.
Here is a simple code that lets you insert data to sql db , this is called from blueprint :
C++
FString ULDAPAuthentication::InsertData(FString TableName, TArray<FKeyValuePair> Data)
{
int length = Data.Num();
std::string tablename(TCHAR_TO_UTF8(*TableName));
FString CName = "";
FString CValue = "";
std::string *ColumnNames = new std::string[length];
std::string *ColumnValues = new std::string[length];
for (int i = 0; i < Data.Num(); i++)
{
std::string columnname(TCHAR_TO_UTF8(*Data*.KeyName));
std::string columnvalue(TCHAR_TO_UTF8(*Data*.Value));
ColumnNames->append(columnname.c_str());
ColumnNames->append(columnvalue.c_str());
}
typedef bool(*_InsertData)(std::string tablename, std::string colname] , std::string value]);
FString filePath = FPaths::Combine(*FPaths::GamePluginsDir(), TEXT("WinAuthentication.dll")); // Concatenate the plugins folder and the DLL file.
void *DLLHandle = NULL;
if (FPaths::FileExists(filePath))
{
DLLHandle = FPlatformProcess::GetDllHandle(*filePath);
}
if (DLLHandle != NULL)
{
_InsertData DLLFuncPtr = NULL;
FString procName = "InsertData";
DLLFuncPtr = (_InsertData)FPlatformProcess::GetDllExport(DLLHandle, *procName);
if (DLLFuncPtr != NULL)
{
bool result = DLLFuncPtr(tablename, ColumnNames, ColumnValues); -> **[FONT=Comic Sans MS]This line throws error. Error doesn't occur if the input parameters are string and not arrays , however if the length of the string exceeds 16 , C# replaces the string with some garbage values.**
return "Successful";
}
}
return "Failed";
}
C# doesn’t know what the heck std::string is. So you shouldn’t be passing them in.
Also, it doesn’t “replace” them with garbage values, it tries to reinterpret data you put onto stack as expected arguments.
In general, you don’t want to use std::string when communicating with dll, unless you can be absolutely sure that dll is using same version of C++ runtime library as your program AND the same compiler. Otherwise funny things might start to happen, especially if your dll will try to modify or return std::strings.
Also… IIRC there are several pure C++ database libraries that can work without that kind of thing with less hassle. Perhaps you could try mysql connector or something similar?
It actually shouldn’t be like this, because you forgot to delete every single array and now have multiple memory leaks in your program.
Use std::vector<char*> or TArray<char*> instead. TArray has GetData() method for situations like this.