Как можно использовать SafeHandle в подписи P/вызов, которая в определенных случаях требует нулевого указателя?

StackOverflow https://stackoverflow.com/questions/8370016

  •  27-10-2019
  •  | 
  •  

Вопрос

Надеемся, что это не слишком неясно для этого, но рассмотрите следующую подпись p/inloke:

[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, Аргумент inputhandle должен быть нулевым указателем, когда аргумент Handletype-SQL_Handle_ENV и не нулевой указатель в противном случае.

Как запечатлеть эту семантику за одну подпись P/вызов? Пожалуйста, укажите пример вызовов в свой ответ. Мое текущее решение - использовать две подписи.

Это было полезно?

Решение

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 статический член.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top