我正在尝试使用C ++ DLL在C#中编辑我的StringBuilder对象。我的C ++代码如下所示:
extern "C" __declspec(dllexport) void __stdcall PrintHead(char* myString)
{
myString = "testIsOkey";
}
我的C#代码是:
[DllImport("StringEdit.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = false)]
public static extern void PrintHead([MarshalAs(UnmanagedType.LPStr)] StringBuilder stringBuilder);
private void button1_Click(object sender, EventArgs e)
{
StringBuilder stringBuilder = new StringBuilder("123456");
PrintHead(stringBuilder);
}
调用PrintHead后,我希望看到stringBuilder对象的值从“123456”更改为“testIsOkey”,但它不会更改。我无法弄清楚我在哪里犯了错误。
感谢您的帮助。
答案 0 :(得分:6)
void __stdcall PrintHead(char* myString) {
myString = "testIsOkey";
}
这不是正确的C ++代码。它只是更改传递给函数的指针。这没有任何副作用。修正:
void __stdcall PrintHead(char* myString) {
strcpy(myString, "testIsOkey");
}
但是从不写这样的interop代码,C ++函数可以很容易地以这种方式破坏垃圾收集堆。这正是你的代码中发生的事情,StringBuilder的容量还不够。您应该添加一个额外的参数,该参数提供传递的缓冲区的大小。修正:
void __stdcall PrintHead(char* myString, size_t bufferSize) {
strcpy_s(myString, bufferSize, "testIsOkey");
}
传递字符串构建器的额外参数的容量,如下所示:
var buffer = new StringBuilder(666);
PrintHead(buffer, buffer.Capacity);
var result = buffer.ToString();
答案 1 :(得分:-1)
是否必须将其标记为ref
或具有其他某些属性,以便.NET知道编组应该双向进行?