【问题标题】:How can a SafeHandle be used in a P/Invoke signature that requires a null pointer in certain cases?在某些情况下,如何在需要空指针的 P/Invoke 签名中使用 SafeHandle?
【发布时间】:2011-12-03 18:44:37
【问题描述】:

希望这对 SO 来说不是太晦涩难懂,但请考虑以下 P/Invoke 签名:

[DllImport("odbc32.dll", CharSet = CharSet.Unicode)]
internal static extern OdbcResult SQLAllocHandle(
    OdbcHandleType HandleType,
    IntPtr InputHandle,
    ref IntPtr OutputHandlePtr);

我想重新设计这个签名以使用 SafeHandles,如下:

[DllImport("odbc32.dll", CharSet = CharSet.Unicode)]
internal static extern OdbcResult SQLAllocHandle(
    OdbcHandleType HandleType,
    MySafeHandle InputHandle,
    ref MySafeHandle OutputHandlePtr);

但是,according to MSDN,当 HandleType 参数为 SQL_HANDLE_ENV 时 InputHandle 参数必须为空指针,否则为非空指针。

如何在单个 P/Invoke 签名中捕获这些语义?请在您的答案中包含一个示例呼叫站点。我目前的解决方案是使用两个签名。

【问题讨论】:

    标签: c# pinvoke dllimport cer


    【解决方案1】:

    SafeHandle 是一个类,因此您应该能够传递null 而不是实际的SafeHandle。空引用在 P/Invoke 中被封送为空指针。

    SafeHandle handle = new SafeHandle();
    OdbcResult result= SQLAllocHandle(OdbcHandleType.SQL_HANDLE_ENV, null, ref handle);
    

    【讨论】:

    • 也可以声明out SafeHandle参数。
    • 在这里不起作用,我从System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success) 得到一个ArgumentNullException
    • 是的,@shf301,这在 P/Invoke 调用中不起作用。你试过了吗?
    【解决方案2】:

    The answer by shf301null 传递给输入参数InputHandle。这对大多数 API 都不起作用(也许它以某种方式解决了 OP 的特定问题,因为他们接受了答案)。

    我使用这种模式:

    [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
    public class RegionHandle : SafeHandleZeroOrMinusOneIsInvalid
    {
        private RegionHandle() : base(true) {}
    
        public static readonly RegionHandle Null = new RegionHandle();
    
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        override protected bool ReleaseHandle()
        {
            return Region.DeleteObject(handle);
        }
    }
    

    这意味着我可以这样做来传递一个空句柄:

    SomeApi(RegionHandle.Null);
    

    类似于IntPtr.Zero 静态成员。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-07
      • 1970-01-01
      • 1970-01-01
      • 2020-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多