Calling Win API in C# with P/Invoke when _Out_ parameters can be NULL or non-NULL -


i'm new c# , i'm learning c# write small tools.

there many windows api pointer parameters null or non-null depends on different use case. question is, how 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 qdc_database_current, last parameter pcurrenttopologyid must not null. when flags other value, pcurrenttopologyid must null.

if parameter declared "out intptr" or "ref intptr", in order api can change referred memory. if passing intptr.zero required api, api call 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 parameter declared "intptr", intptr.zero can passed null pointer. if passing intptr, api call 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, when number of different parameters combination can numerous.

any suggestion?

when have optional parameter enum, have here, think there little alternative declare 2 separate overloads. overload use pass null declares parameter this:

intptr pcurrenttopologyid 

you pass intptr.zero when calling overload.

the other overload, 1 call when pass non-null value declares parameter this:

out displayconfig_topology_id pcurrenttopologyid 

where displayconfig_topology_id c# enum base type of int.

your code gets second variant wrong because declare out intptr pcurrenttopologyid. intptr wrong size on 64 bit (8 bytes rather 4).

if wish declare single p/invoke , not use overloads transfer work elsewhere. have pick first option:

intptr pcurrenttopologyid 

fine when want pass intptr.zero. when need pass address of enum variable need pin variable using gchandle , addrofpinnedobject. possible yet more boilerplate. so, take pick!


Comments

Popular posts from this blog

javascript - Any ideas when Firefox is likely to implement lengthAdjust and textLength? -

matlab - "Contour not rendered for non-finite ZData" -

delphi - Indy UDP Read Contents of Adata -