pinvoke - Determine C# P/Invoke Structure Alignment at Runtime -
i'm trying write p/invoke signatures windows setupapi calls, , i've encountered following problem packing of setupapi's structures:
// excerpt setupapi.h #if defined(_win64) #include <pshpack8.h> // assume 8-byte (64-bit) packing throughout #else #include <pshpack1.h> // assume byte packing throughout (32-bit processor) #endif
now, means can't set structlayoutattribute.pack
property constant value.
i tried doing following:
[structlayout(layoutkind.sequential, pack = environment.is64bitprocess ? 8 : 1)] public struct sp_devinfo_data { public uint cbsize; public guid classguid; public uint devinst; public intptr reserved; }
as expected, fails following compilation error:
an attribute argument must constant expression, typeof expression or array creation expression of attribute parameter type
i'd avoid #if
, setting different compilation platforms, opposed any cpu
. can determine packing of c# structure @ run-time?
no, packing compile-time concept, because determines (among other things) overall size of type. can't change @ run-time.
in case, if you're not willing have separate builds x86 , x64, you'll have marshalling yourself. @hans passant clean way achieve this:
- define 2 structures,
sp_devinfo_data32
,sp_devinfo_data64
, - define method overload each structure
- at run-time, select structure create , call appropriate overload.
it this:
[structlayout(layoutkind.sequential, pack = 1)] public struct sp_devinfo_data32 { /* stuff */ } [structlayout(layoutkind.sequential, pack = 8)] public struct sp_devinfo_data64 { /* stuff */ } [dllimport("setupapi.dll")] public static extern void function(ref sp_devinfo_data32 data); [dllimport("setupapi.dll")] public static extern void function(ref sp_devinfo_data64 data); public void dostuff() { if (environment.is64bitprocess) { var data = new sp_devinfo_data64 { cbsize = marshal.sizeof(typeof(sp_devinfo_data64)) }; function(ref data); } else { var data = new sp_devinfo_data32 { cbsize = marshal.sizeof(typeof(sp_devinfo_data32)) }; function(ref data); } }
Comments
Post a Comment