在某些情况下需要空指针的P/Invoke签名中如何使用SafeHandle ?
本文关键字:Invoke SafeHandle 何使用 情况下 空指针 | 更新日期: 2023-09-27 18:16:29
希望这对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);
然而,根据MSDN,当HandleType参数为SQL_HANDLE_ENV时,InputHandle参数必须为空指针,否则为非空指针。
如何在单个p/Invoke签名中捕获这些语义?请在你的回答中包括一个呼叫地点的例子。我目前的解决方案是使用两个签名。
SafeHandle
是一个类,所以你应该能够通过null
而不是实际的SafeHandle
。空引用在P/Invoke中被封送为空指针。
SafeHandle handle = new SafeHandle();
OdbcResult result= SQLAllocHandle(OdbcHandleType.SQL_HANDLE_ENV, null, ref handle);
shf301的答案传递null
作为输入参数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
静态成员很像