希望这对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签名中捕获这些语义?请在答案中包含示例呼叫站点。我目前的解决方案是使用两个签名。
答案 0 :(得分:4)
SafeHandle
是一个类,因此您应该能够传递null
而不是实际的SafeHandle
。空引用在P / Invoke中被编组为空指针。
SafeHandle handle = new SafeHandle();
OdbcResult result= SQLAllocHandle(OdbcHandleType.SQL_HANDLE_ENV, null, ref handle);
答案 1 :(得分:1)
The answer by 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
静态成员。