假设这个 C 函数:
void do_something(const char* str)
它将字符串存储在某处稍后参考.
此外,我在 C# 中有这个签名来调用这个函数:
[DllImport("NativeLib")]
static extern void do_something(string str);
现在,将字符串传递给此方法时我需要做什么:
- 我需要钉住绳子吗(用
GCHandle.Alloc()
)(或者编组器正在创建副本)?
- 如果我确实需要固定它,我是否传递“原始”字符串(即我传递给的字符串)
GCHandle.Alloc()
)?或者我需要传递返回值GCHandle.AddrOfPinnedObject()
?
- Is
string
正确的数据类型(对于do_something
) 在这种情况下?或者我应该使用IntPtr
反而?
通过互操作边界存储指针是一个非常糟糕的主意,请尽一切努力修改 C 代码以制作字符串的副本。
按照赞成答案中的建议固定字符串是行不通的,pinvoke 编组器必须将字符串转换为 char* 并在进行本机调用后释放转换后的字符串,从而使指针无效。您必须自己整理字符串。将参数声明为 IntPtr 并使用 Marshal.StringToHGlobalAnsi() 创建指针值。
或者使用 Marshal.StringToCoTaskMemAnsi(),它从 COM 堆中分配。这是你真正的问题,没有很好的场景来释放字符串。 C 代码无法释放该字符串,因为它不知道它是如何分配的。您的 C# 代码无法释放该字符串,因为它不知道 C 代码何时处理完该指针。这就是为什么复制字符串如此重要。如果您只进行几次此调用,您就可以忍受内存泄漏。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)