我想导入这样的函数:
[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", EntryPoint="FuncUtf16", ExactSpelling=true, PreserveSig=true, 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中声明一个函数有什么问题?
答案 0 :(得分:7)
为返回char* / wchar_t*
的方法编写PInvoke签名需要非常小心,因为CLR特殊情况string
返回类型。它做出以下假设
char*
string
的内存
CoTaskMemAlloc
如果其中任何一个不正确(通常是这种情况),那么程序将遇到错误。
一般情况下,最好只返回IntPtr
并手动封送字符串,就像使用PtrToStringUni
一样。