c# - Reading binary file into struct -
i know has been answered after reading other questions i'm still no solution. have file written following c++ struct:
typedef struct mystruct{ char name[127]; char s1[2]; char mailbox[149]; char s2[2]; char routeid[10]; } my_struct; my approach able parse 1 field @ time in struct, issue cannot s1 , mailbox parse correctly. in file, s1 field contains "\r\n" (binary 0d0a), , causes parsing code not parse mailbox field correctly. here's parsing code:
[structlayout(layoutkind.explicit, size = 0x80 + 0x2 + 0x96)] unsafe struct my_struct { [fieldoffset(0)] [marshalas(unmanagedtype.byvaltstr, sizeconst = 0x80)] public string name; [fieldoffset(0x80)] public fixed char s1[2]; /* not work, "could not load type 'my_struct' ... because contains object field @ offset 130 incorrectly aligned or overlapped non-object field." */ [fieldoffset(0x80 + 0x2)] [marshalas(unmanagedtype.byvaltstr, sizeconst = 0x96)] public string mailbox; } if comment out last field , reduce struct's size 0x80+0x2 work correctly first 2 variables.
one thing note name , mailbox strings contain null terminating character, since s1 doesn't have null-terminating character seems messing parser, don't know why because me looks code explicitly telling marshaler s1 field in struct fixed 2-char buffer, not null-terminated string.
here pic of test data (in code seek past first row in binaryreader, "name" begins @ 0x0, not 0x10). 
here's 1 way, doesn't use unsafe (nor particularly elegant/efficient)
using system.text; using system.io; namespace readcppstruct { /* typedef struct mystruct{ char name[127]; char s1[2]; char mailbox[149]; char s2[2]; char routeid[10]; } my_struct; */ class mystruct { public string name { get; set; } public string mailbox { get; set; } public string routeid { get; set; } } class program { static string getstring(encoding encoding, byte[] bytes, int index, int count) { string retval = encoding.getstring(bytes, index, count); int nullindex = retval.indexof('\0'); if (nullindex != -1) retval = retval.substring(0, nullindex); return retval; } static mystruct readstruct(string path) { byte[] bytes = file.readallbytes(path); var utf8 = new utf8encoding(); var retval = new mystruct(); int index = 0; int cb = 127; retval.name = getstring(utf8, bytes, index, cb); index += cb + 2; cb = 149; retval.mailbox = getstring(utf8, bytes, index, cb); index += cb + 2; cb = 10; retval.routeid = getstring(utf8, bytes, index, cb); return retval; } // http://stackoverflow.com/questions/30742019/reading-binary-file-into-struct static void main(string[] args) { mystruct ms = readstruct("my_struct.data"); } } }
Comments
Post a Comment