8

うまくいけば、これは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引数はnullポインターである必要があり、それ以外の場合はnull以外のポインターである必要があります。

これらのセマンティクスを単一のP/Invoke署名に取り込むにはどうすればよいですか?回答にコールサイトの例を含めてください。私の現在の解決策は、2つの署名を使用することです。

4

2 に答える 2

3

SafeHandlenullはクラスなので、実際ではなく合格できるはずですSafeHandle。null参照は、P/Invokeでnullポインターとしてマーシャリングされます。

SafeHandle handle = new SafeHandle();
OdbcResult result= SQLAllocHandle(OdbcHandleType.SQL_HANDLE_ENV, null, ref handle);
于 2011-12-03T18:50:25.697 に答える
2

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);
    }
}

これは、nullハンドルを渡すためにこれを実行できることを意味します。

SomeApi(RegionHandle.Null);

IntPtr.Zeroこれは、静的メンバーが存在する方法と似ています。

于 2013-12-09T18:07:54.043 に答える