I'm new to C# and I'm learning C# by write some small tools.
There are many Windows API whose pointer parameters could be NULL or non-NULL depends on different use case. My question is, how to declare such parameters in DllImport?
For example:
LONG QueryDisplayConfig(
_In_ UINT32 Flags,
_Inout_ UINT32 *pNumPathArrayElements,
_Out_ DISPLAYCONFIG_PATH_INFO *pPathInfoArray,
_Inout_ UINT32 *pNumModeInfoArrayElements,
_Out_ DISPLAYCONFIG_MODE_INFO *pModeInfoArray,
_Out_opt_ DISPLAYCONFIG_TOPOLOGY_ID *pCurrentTopologyId
);
When Flags
is QDC_DATABASE_CURRENT
, the last parameter pCurrentTopologyId
must NOT be null.
When Flags
is other value, pCurrentTopologyId
must be null.
If the parameter is declared as "out IntPtr" or "ref IntPtr", in order that the API can change the referred memory. However if passing it IntPtr.Zero as required by the API, the API call will return ERROR_NOACCESS.
[DllImport(user32_FileName, SetLastError=true)]
internal static extern int QueryDisplayConfig(
[In] QDC_FLAGS Flags,
[In, Out] ref UInt32 pNumPathArrayElements,
[Out] DISPLAYCONFIG_PATH_INFO[] pPathInfoArray,
[In, Out] ref UInt32 pNumModeInfoArrayElements,
[Out] DISPLAYCONFIG_MODE_INFO[] pModeInfoArray,
out IntPtr pCurrentTopologyId
);
If the parameter is declared as "IntPtr", then IntPtr.Zero can be passed as the NULL pointer. However if passing a IntPtr, the API call will also return ERROR_NOACCESS.
[DllImport(user32_FileName, SetLastError=true)]
internal static extern int QueryDisplayConfig(
[In] QDC_FLAGS Flags,
[In, Out] ref UInt32 pNumPathArrayElements,
[Out] DISPLAYCONFIG_PATH_INFO[] pPathInfoArray,
[In, Out] ref UInt32 pNumModeInfoArrayElements,
[Out] DISPLAYCONFIG_MODE_INFO[] pModeInfoArray,
IntPtr pCurrentTopologyId
);
I don't expect declaring different version of extern functions, especially when the number of different parameters combination can be numerous.
Any suggestion?