I connected a dll to my c# code to return a string from it:
extern "C" __declspec(dllexport) Dll_NIRS_API void realize(char*)
void realize(char* buf)
{
...
wstring full_text;
// operations with full_text
char* fill = (char*)(full_text.c_str());
strcpy(buf, fill);
}
Connecting to C#:
[DllImport("dll_name.dll", CharSet = CharSet.Unicode)]
public static extern void realize(StringBuilder text);
Then I use this function and put the resulting string in a textBox:
StringBuilder text = new StringBuilder(100);
realize(text);
textBox4.Text = text.ToString();
But instead of text: РАЗВОРОТ(1, 1.1, 1.2, 1.3, 1.4) РАЗВОРОТ(1, 2.1, 2.2, 2.3, 2.4) the textBox outputs this: РАЗВОРОТ(듹翼
The "full_text" variable is filled in correctly, but I'm not sure about the "fill" variable, maybe the problem is in strcpy or in the dll export.
I use StringBuilder
on the advice from this question: Passing strings from C# to C DLL and back -- minimal example
EDIT
I partially solved the problem, now the entire text is displayed in the textBox (and not just part of it, as it was before). I just converted full_text
from wstring
to string
for use in strcpy
. I also changed the CharSet.Unicode
to CharSet.Ansi
. However, the text is now like this:
Р РђР—Р’РћР РћРў(1, 1.1, 1.2, 1.3, 1.4)Р РђР—Р’РћР РћРў(1, 2.1, 2.2, 2.3, 2.4)
CodePudding user response:
There are two (easy) string marshalling options using P/Invoke:
- Either declare
[CharSet = CharSet.Ansi]
in C# and havechar*
in C. This requires that the C library uses the "ANSI" character set, which seems not to be the case here. - Or declare
[CharSet = CharSet.Unicode]
in C# and havewchar_t*
in C
For the second option, the last statements should be:
wchar_t* fill = full_text.c_str();
wcscpy(buf, fill);
Big caveat: strcpy/wcscpy is dangerous as it may overwrite memory you did not allocate. I strongly recommend replacing it with:
wcscpy_s(buf, size, fill);
size
would be the buffer size (max number of characters, including terminating NUL) and has to be passed ad additional parameter to the method.