Home > Software design >  Problem with string output in c# after exporting from c dll
Problem with string output in c# after exporting from c dll

Time:11-22

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 have char* 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 have wchar_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.

  • Related