I have been struggling for a day now to get this work. It works well on windows but not on Linux with mono.
What I am trying to achieve
C# wrapper
[DllImport("MyLib.dll", CharSet = CharSet.Unicode)]
public static extern int MyFunction(StringBuilder str);
StringBuilder myString = new StringBuilder(255);
var ret = MyFunction(myString);
Console.WriteLine("Result: {0}",myString.ToString());
C++ shared lib (.dll or .so)
WRAPPER_API int _stdcall MyFunction(wchar_t* str)
{
wcscpy(str,L"this is a test");
return 0;
}
Results
Windows:
Result: this is a test
Linux:
Result: t
On mono the returned string contains only the first character of the string. I tried with ANSI string changing wchar_t* to char* and wcscpy to strcpy and it works.
My testing environment
Linux Ubuntu 32 bits 12.04 LTS / Mono 4.3.2
Windows 7 64 bits .Net 4.5
Other questions and references
How do I marshal wchar_t* from C++ to C# as an out parameter or return value?
http://www.mono-project.com/docs/advanced/pinvoke/#passing-caller-modifiable-strings
Edit: Thanks to @Xanatos's answer I was able to solve my issue by using u16string (I have g++ 4.8.4 and enable c++11 standard):
WRAPPER_API int _stdcall MyFunction(chart16_t* str)
{
u16string someString(u"some unicode string");
someString.copy(str, someString.length());
return 0;
}