I am trying to get string from C++ DLL to C#. It outputs incorrect symbols - {栠搂珯獲긋ݳݳ贈琹玴ɡݳ⻜}
Here is my code: C++ DLL
_declspec(dllexport) int __stdcall myClass(LPCTSTR& z)
{
z = _T("Test String");
return 0;
}
My C# code reading C++ DLL:
[DllImport("ecrClassDll.dll", CharSet = CharSet.Unicode)]
static extern void myClass(StringBuilder z);
static void Main(string[] args)
{
StringBuilder z = new StringBuilder();
myClass(z);
}
First, make sure you defined the UNICODE macro in C++, so that _T outputs wchar_t data, and LPCTSTR means const wchar_t*. That's what CharSet.Unicode expects. By the way, if you don't intend to support an ANSI version too, I wouldn't bother with all this _T stuff and just use Unicode everywhere, the code will be simpler.
Also, your C++ function returns an int, but your C# function expects a void. You have a mismatch there (unless you intended to set PreserveSig to false).
On the C# side, when you provide a StringBuilder, it means you provide a buffer to the C++ side, and you expect it to fill that buffer. The correct usage would be something like this:
_declspec(dllexport) int __stdcall myClass(LPCTSTR z, int zSize)
{
_tcscpy_s(z, zSize, _T("Test String"));
return 0;
}
[DllImport("ecrClassDll.dll", CharSet = CharSet.Unicode)]
static extern int myClass(StringBuilder z, int zSize);
static void Main(string[] args)
{
StringBuilder z = new StringBuilder(256);
myClass(z, z.Capacity);
}
But your code returns a pointer to a static string, which the marshaller doesn't expect here.
If you'd like to keep your C++ code as-is, you could try this instead:
[DllImport("ecrClassDll.dll", CharSet = CharSet.Unicode)]
static extern int myClass(out string z);
static void Main(string[] args)
{
string z;
myClass(out z);
}
I admit I didn't test it, but it should work as this C# signature matches the C++ signature.
If everything fails, you could try to marshal the data by yourself:
[DllImport("ecrClassDll.dll")]
static extern unsafe int myClass(void** z);
static unsafe void Main(string[] args)
{
void* z;
myClass(&z);
var str = Marshal.PtrToStringUni(new IntPtr(z));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With