Как можно использовать SafeHandle в подписи P/вызов, которая в определенных случаях требует нулевого указателя?
Вопрос
Надеемся, что это не слишком неясно для этого, но рассмотрите следующую подпись 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
статический член.