gpt4 book ai didi

c# - MarshalAs(UnmanagedType.LPWStr) 和 Marshal.PtrToStringUni() 之间的区别

转载 作者:行者123 更新时间:2023-11-30 14:12:56 29 4
gpt4 key购买 nike

我想导入这样一个函数:

[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 中声明函数有什么问题?

最佳答案

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

  • char* 转换为string 后必须释放内存
  • 内存是用CoTaskMemAlloc分配的

如果其中任何一个不成立(通常是这种情况),那么程序就会出错。

一般来说,最好简单地返回一个 IntPtr 并像使用 PtrToStringUni 那样手动编码字符串。

关于c# - MarshalAs(UnmanagedType.LPWStr) 和 Marshal.PtrToStringUni() 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15793736/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com