Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can a SafeHandle be used in a P/Invoke signature that requires a null pointer in certain cases?

Hopefully this isn't too obscure for SO, but consider the following P/Invoke signature:

[DllImport("odbc32.dll", CharSet = CharSet.Unicode)]
internal static extern OdbcResult SQLAllocHandle(
    OdbcHandleType HandleType,
    IntPtr InputHandle,
    ref IntPtr OutputHandlePtr);

I'd like to redesign this signature to use SafeHandles, as follows:

[DllImport("odbc32.dll", CharSet = CharSet.Unicode)]
internal static extern OdbcResult SQLAllocHandle(
    OdbcHandleType HandleType,
    MySafeHandle InputHandle,
    ref MySafeHandle OutputHandlePtr);

However, according to MSDN, the InputHandle argument must be a null pointer when the HandleType argument is SQL_HANDLE_ENV and a non-null pointer otherwise.

How do I capture those semantics in a single P/Invoke signature? Please include an example call-site in your answer. My current solution is to use two signatures.

like image 298
davidzarlengo Avatar asked Dec 03 '11 18:12

davidzarlengo


1 Answers

SafeHandle is a class so you should be able to pass null rather than an actual SafeHandle. A null reference is marshaled as a null pointer in P/Invoke.

SafeHandle handle = new SafeHandle();
OdbcResult result= SQLAllocHandle(OdbcHandleType.SQL_HANDLE_ENV, null, ref handle);
like image 200
shf301 Avatar answered Nov 14 '22 23:11

shf301