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

Popular posts from this blog

google chrome - Developer tools - How to inspect the elements which are added momentarily (by JQuery)? -

angularjs - Showing an empty as first option in select tag -

php - Cloud9 cloud IDE and CakePHP -