c# - How to set a fixed buffer field element using reflection? -


here's typical unsafe struct declaration includes fixed buffer field:

[structlayout(layoutkind.explicit, pack = 1)] public unsafe struct mystruct {     ...      [fieldoffset(6)]     public fixed ushort myfixedbuffer[28];      ... } 

how set element of myfixebuffer using reflection?

you not need reflection. need address of struct want set. can use

byte* pstruct = xxxx byte* pmyfixedbuffer = pstruct+6;  // fieldoffset 6 tells me  *(pmyfixedbuffer+i) = yourbytevalue;  // set i-th element in myfixedbuffer 

i guess having problems address of struct @ because passed value methods want patch in different values. long struct not assigned class member variable instance can somehow access outside not able patch @ runtime.

since class public , field public there no reason use reflection or unsafe code @ all. guess class not actual 1 struggling with.

you can use reflection find out class layout @ point need hard code field want patch. can use layout information gained reflection , determine address @ runtime. need fieldoffset attribute value of field , use pointer offset it.

please note array myfixedbuffer not real array in struct since embedded in struct. usual object pointer gettype things not work since array not managed fixed size buffer has no mt (method table pointer) @ all. @ point need deal raw offsets , patch in bytes after.

below example uses reflection if want know how deal value type if want build dynamic uses value types or e.g. serializer.

[structlayout(layoutkind.explicit, pack = 1)] public unsafe struct mystruct {      [fieldoffset(6)]     public fixed ushort myfixedbuffer[28];      [fieldoffset(62)]     public byte next; }  class program {     unsafe static void main(string[] args)     {         var field = typeof(mystruct).getfield("myfixedbuffer");         int offset = field.customattributes.where(x => x.attributetype.equals(typeof(fieldoffsetattribute)))                                                 .selectmany(x => x.constructorarguments)                                                 .select(x => x.value)                                                 .cast<int>()                                                 .first();          keyvaluepair<type,int> fixedbufferdescription = field.customattributes.where(x => x.attributetype.equals(typeof(fixedbufferattribute)))                                                    .select(x => x.constructorarguments)                                                    .select(x => new keyvaluepair<type, int>((type)x[0].value, (int)x[1].value))                                                    .first();          int fixedbuferlen = marshal.sizeof(fixedbufferdescription.key) * fixedbufferdescription.value;           mystruct tmp = new mystruct();         byte* raw = (byte*) &tmp;         short* pmyarray = (short *) (raw + offset);          (int = 0; < fixedbuferlen/marshal.sizeof(fixedbufferdescription.key); i++)         {             *(pmyarray + i) = (short) i;         }      } } 

that should trick.


Comments

Popular posts from this blog

Magento/PHP - Get phones on all members in a customer group -

php - .htaccess mod_rewrite for dynamic url which has domain names -

Website Login Issue developed in magento -