我将一个dll连接到我的c#代码中,从中返回一个字符串:
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);
}
连接到c#:
[DllImport("dll_name.dll", CharSet = CharSet.Unicode)]
public static extern void realize(StringBuilder text);
然后我使用这个函数,并把结果字符串放在一个textBox:
StringBuilder text = new StringBuilder(100);
realize(text);
textBox4.Text = text.ToString();
而不是文本:РАЗВОРОТ(1,1.1, 1.2, 1.3, 1.4)РАЗВОРОТ(1,2.1, 2.2, 2.3, 2.4)textBox输出如下:РАЗВОРОТ(듹)
"full_text"变量是正确填写的,但是我不确定"fill"变量,也许问题是在策略或在DLL导出。我使用StringBuilder
对这个问题的建议:从c#传递字符串到c++ DLL并返回—最小示例
编辑我部分地解决了这个问题,现在整个文本显示在textBox中(而不是像以前那样只是其中的一部分)。我只是将full_text
从wstring
转换为string
用于strcpy
。我还将CharSet.Unicode
更改为CharSet.Ansi
。然而,现在的文本是这样的:РРђР——РРћРРћРў(1.1,1.2,1.3,1.4)РРђР——РРћРРћРў(2.1,2.2,2.3,2.4)
使用p/Invoke有两个(简单的)字符串封送选项:
- 要么在c#中声明
[CharSet = CharSet.Ansi]
,在C中声明char*
。这要求C库使用"ansi";字符集,这似乎不是这里的情况。 - 或者在c#中声明
[CharSet = CharSet.Unicode]
,在C 中声明
wchar_t*
对于第二个选项,最后的语句应该是:
wchar_t* fill = full_text.c_str();
wcscpy(buf, fill);
大警告: strcpy/wcscpy isdangerous因为它可能会覆盖您没有分配的内存。我强烈建议将其替换为:
wcscpy_s(buf, size, fill);
size
将是缓冲区大小(最大字符数,包括终止NUL),必须作为附加参数传递给方法。