gpt4 book ai didi

c# - 在执行 P/Invoke 调用时应该在哪些情况下固定参数

转载 作者:太空宇宙 更新时间:2023-11-03 11:25:09 25 4
gpt4 key购买 nike

我有一个 DLL,我需要从中 P/调用以下 C 方法:

int DAOpen(HANDLE *hOpen, UNIT *flags, void *callback, char *userData)

我提出了以下 C# 签名:

[DllImportAttribute("<libName>", EntryPoint="DAOpen")]  
static extern int DAOpen(
out IntPtr hOpen,
ref uint flags,
IntPtr callback,
IntPtr userData);

假设 native 代码保留对所有参数的引用的时间长于 P/Invoke 调用的持续时间:

  1. 除了保留 hOpen 的实异常(exception),我还应该固定它吗?

  2. 我应该保留对 flags 变量的引用吗?我是否也应该固定它,因为它在这种特殊情况下作为引用传递?

  3. 我正在按以下方式分配我的回调委托(delegate):

    私有(private) IntPtr callBackOnNativeEvents;
    ...
    this.callBackOnNativeEvents = Marshal.GetFunctionPointerForDelegate(
    new CallBack(this.CallBackOnNativeEvents));

    我是否应该保留对委托(delegate)本身的引用(而不仅仅是指针)?我也应该固定它吗?

  4. 最后,我按以下方式定义了 userData 参数:

    私有(private) IntPtr 用户数据;
    ...
    string userName = "test";
    this.userData = Marshal.StringToHGlobalAnsi(userName);

    我应该保留对字符串的引用吗?我也应该固定它吗? API 文档指出它将字符串内容复制到非托管内存,但我不确定它是否复制了引用的内容。

最佳答案

  1. 无需固定hOpen,它具有值类型语义。
  2. 如果 DLL 写入由 flags 指向的地址,并且在原始函数返回后这样做,那么您需要以一种或另一种方式固定它(以及保持它的事件和安全从 GC 的手中)。
  3. 回调函数指针已经有效固定。您需要保留对委托(delegate)的引用,但不需要固定它,因为 native thunk is allocated from the unmanged heap .
  4. 你不需要在这里做任何特别的事情,因为你正在传递一个 IntPtr 并且它背后的内存是固定的。您不需要保留对字符串的引用,因为它与 StringToHGlobalAnsi 返回的 IntPtr 完全断开。它只有调用 StringToHGlobalAnsi 时字符串内容的副本。

我不得不说,我仍然怀疑这个 DLL 真的可以按照您所说的那样做。我怀疑其他事情出了问题,您误诊为 DLL 从一次调用中保留指针参数,然后在后续调用中修改它们的内容。我发现这非常难以置信,但当然只有你才能真正知道。如果我处在您的位置,我只会问 DLL 供应商的问题。

关于c# - 在执行 P/Invoke 调用时应该在哪些情况下固定参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9621048/

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