.net - How to get aligned size of CLR blittable struct? -


i making class similar safebuffer targetting .net 2.0. 1 of functions void readarray<t>(long position, t[] array, int offset, int count) (or writearray) reads/writes series of (blittable) structures into/from array.

my first guess use marshal.ptrtostructure/structuretoptr along advancing marshal.sizeof. looking @ il safebuffer.readarray shows uses marshal.alignedsizeof<t>() advancement (an internal method). function defined as:

uint s = marshal.sizeof<t>(); if (s == 1u || s == 2u || intptr.size == 8 && s == 4u) { return s; } return marshal.alignedsizeoftype(typeof(t)); // internalcall 

that method defined in .net 4.0 unavailable me (and not in rotor).

my idea use marshal.unsafeaddrofpinnedarrayelement on adjacent elements in array didn't work. here testing code:

using system; using system.reflection; using system.runtime.interopservices;  namespace test {     class program     {         [structlayout(layoutkind.sequential)]         struct         {             byte a;             short x;             byte b;         }          private static methodinfo marshalalignedsizeof;         static int malignedsizeof(type t)         {             if (marshalalignedsizeof == null) { marshalalignedsizeof = typeof(marshal).getmethod("alignedsizeof", bindingflags.nonpublic | bindingflags.static); }             return (int)(uint)marshalalignedsizeof.makegenericmethod(t).invoke(null, null);         }          static int alignedsizeof(type t)         {             array = array.createinstance(t, 0);             gchandle pin = gchandle.alloc(a, gchandletype.pinned);             try             {                 return (int)(marshal.unsafeaddrofpinnedarrayelement(a, 1).toint64() - marshal.unsafeaddrofpinnedarrayelement(a, 0).toint64());             }             { pin.free(); }         }          unsafe static void main(string[] args)         {             console.writeline("sizeof:       " + sizeof(a));             console.writeline("sizeof:       " + marshal.sizeof(typeof(a)));             console.writeline("aligned size: " +  alignedsizeof(typeof(a)));             console.writeline("mars algn sz: " + malignedsizeof(typeof(a)));         }     } } 

which outputs 6, 6, 6,8 on x86 or x64 (notice how native alignedsizeof different?).

so questions are:

  1. discussion: why aligned size different normal size? in c/c++ sizeof() aligned value. (sizeof(arr)/sizeof(arr[0]) works)
  2. is there managed way (with or without unsafe code) aligned size of blittable generic struct?
  3. should using sizeof() , not care alignment? in case doing block-transfer...

you have pick option 3, don't have access structuretoptrnative(). can use marshal.structuretoptr() copy value type value , demands use marshal.sizeof() measure it.

that's buck stops. other questions, exact layout rules clr uses internal storage pretty unusual , hard reverse engineer. size of example structure when stored in array indeed 8, 2 bytes of padding added. 6 required fields aligned properly. no idea why this, buried in clr internals. if want experiment debugger see in practice this answer shows how that.

    static void main(string[] args) {         var arr = new a[] { new a() { = 1, x = 2, b = 3}, new { = 0x11, x = 0x12, b = 0x13 }};     }  // <== set breakpoint here 

and put "&arr" in debugger memory window's address box

 0x000000001d67de70  98 73 14 03 00 00 00 00 01 00 02 00 03 00 00 00 11 00 12 00 13 00 00 00                                               ^ arr[0]                ^ arr[1] 

Comments

Popular posts from this blog

ios - iPhone/iPad different view orientations in different views , and apple approval process -

java Extracting Zip file -

C# WinForm - loading screen -