微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – MarshalAs(UnmanagedType.LPWStr)和Marshal.PtrToStringUni()之间的差异

我想导入这样的函数

[return: MarshalAs(UnmanagedType.LPWStr)]
[DllImport("DLL.dll",EntryPoint="FuncUtf16",ExactSpelling=true,PreserveSig=true,CharSet=CharSet.Unicode)]
public static extern string Func();

但这给了我一个这样的错误

“Windows在Test.exe中触发了断点.这可能是由于堆的损坏,这表明Test.exe或其加载的任何DLL中存在错误.”

当我反复按“继续”时,该功能确实给出了预期的输出.但是,当我有机会上述声明时:

[DllImport("DLL.dll",CharSet=CharSet.Unicode)]
public static extern IntPtr Func();

(将返回类型更改为IntPtr)并按如下方式调用它:

Dim a As IntPtr = Func()
Dim Str As String = Runtime.InteropServices.Marshal.PtrToStringUni(a)

,我没有错误,它工作得很好!使用“MarshalAs”方式在dll中声明一个函数有什么问题?

解决方法

为返回char * / wchar_t *的方法编写PInvoke签名需要非常小心,因为CLR特殊情况字符串返回类型.它做出以下假设

>转换为字符串后,必须释放char *的内存
>内存分配了CoTaskMemAlloc

如果其中任何一个不正确(通常是这种情况),那么程序将遇到错误.

一般来说,最好只返回一个IntPtr并手动编组字符串,就像你使用PtrToStringUni一样.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐