Return string from c++ dll export function called from c#
I have had this problem too, recently, and though I have a solution for you, sadly I can't really explain it. I haven't found a sound explanation yet.
my c++ code for retrieving a string is:
extern "C" { __declspec(dllexport) void __GetValue__(char* str, int strlen); }
and my C# code:
[DllImport("MyDLL.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void __GetValue__(StringBuilder str, int strlen);
So as you can see, instead of returning a value, you can supply a string (by using StringBuilder) and let C++ fill in the data like:
void __GetValue__(char* str, int strlen) {
std::string result = "Result";
result = result.substr(0, strlen);
std::copy(result.begin(), result.end(), str);
str[std::min(strlen-1, (int)result.size())] = 0;
}
And for completeness the C# code to request the string:
public String GetValue() {
StringBuilder str = new StringBuilder(STRING_MAX_LENGTH);
__GetValue__(str, STRING_MAX_LENGTH);
return str.ToString();
}
How about this (Note, it assumes correct lengths - you should pass in the buffer length and prevent overflows, etc):
extern "C" __declspec(dllexport) void __cdecl getDataFromTable(char* tableName, char* buf)
{
std::string st = getDataTableWise(statementObject, columnIndex);
printf(st.c_str());
strcpy(buf, st.c_str());
}
Then in C#:
[DllImport("\\SD Card\\ISAPI1.dll")]
private static extern string getDataFromTable(byte[] tablename, byte[] buf);
static void Main(string[] args)
{
byte[] buf = new byte[300];
getDataFromTable(byteArray, buf);
Console.writeLine(System.Text.Encoding.ASCII.GetString(buf));
}
Note, this does make some assumptions about character encodings in your C++ app being NOT unicode. If they are unicode, use UTF16 instead of ASCII.
The .NET runtime uses unicode (wchar_t) strings, not ascii (char) so this require some changes. You should also consider that .NET has no way to free a string that has been allocated by a C/C++ application, so having the buffer pre-allocated and passed in from C# is the only safe way to manage this without memory leaks or worse.