.net - While using P/Invoke for c to c# and mashalling c struct to c# generates AccessViolationException, what could be the reason? -
i have use c++ dll in project p/invoke i'm calling function involves struct well, generate accessviolationexception.
the specifics below: following c++ function.
int bii_read_transaction_log_ex(int ioption, int iupdateflag, int *imaxentries, bii_transaction_log_ex *log)
here method declaration.
[dllimport(@"c:\program files (x86)\bioscrypt\securesdk\dll\bii_v1100.dll", entrypoint = "bii_read_transaction_log_ex")] public unsafe static extern int gettransactionlogs(int option, int updateflag, ref int maxenteries, ref bii_transaction_log_ex[] transactionlogs);
it involves following struct.
typedef struct { unsigned int id; // id of template action recorded unsigned char reserved_1; unsigned char index; // index of template action recorded unsigned short year; // years since 2002 action recorded unsigned char month; // months since january action recorded (0-11) unsigned char unsigned char day; // day of month action recorded (1-31) unsigned char hour; // hour (0-23), minute , second (0-59) – time of action unsigned char min; unsigned char sec; unsigned char trans_code; // trans_code, data1, data2, data3 – see table below unsigned char flag_port; //bit 5. bit 6 bit 7 unused bit 0-4: port (0 – host, 1 – aux, 3–wiegand, 5 – gpi0, 6 – gpi1, 8 – search) unsigned char trans_log_data_1; unsigned char trans_log_data_2; unsigned char trans_log_data_3; unsigned char reserved_2; unsigned char status; //0 if action failed, 1 if action succeeded char name[16]; // name field of template log stored unsigned short duration; // enroll / verify duration in milliseconds unsigned short template_size; // size of template in bytes log stored signed short error_code; // error code if enroll / verify failed unsigned char sensor_type; // sensor type connected device unsigned char unit_id; // unit id assigned device, same net id (get/set command net id bii_get_netid / bii_set_netid) unsigned char admin_level; // admin level of template log stored unsigned char rsz_3; /* reserved */ unsigned char rsz_4; /* reserved */ unsigned char rsz_5; /* reserved */ char ta_msg[16]; /*f1,f2,f3,f4 key message */ }bii_transaction_log_ex;
my implemenation of struct in c# following.
[structlayout(layoutkind.sequential, pack = 1)] public struct bii_transaction_log_ex { public uint32 id; // id of template action recorded public byte reserved_1; public byte index; // index of template action recorded public uint16 year; // years since 2002 action recorded public byte month; // months since january action recorded (0-11) unsigned char public byte day; // day of month action recorded (1-31) public byte hour; // hour (0-23), minute , second (0-59) – time of action public byte min; public byte sec; public byte trans_code; // trans_code, data1, data2, data3 – see table below public byte flag_port; //bit 5. bit 6 bit 7 unused bit 0-4: port (0 – host, 1 – aux, 3– wiegand, 5 – gpi0, 6 – gpi1, 8 – search) public byte trans_log_data_1; public byte trans_log_data_2; public byte trans_log_data_3; public byte reserved_2; public byte status; //0 if action failed, 1 if action succeeded [marshalas(unmanagedtype.byvalarray, sizeconst = 16)] public byte[] name; //char name[16]; // name field of template log stored public uint16 duration; // enroll / verify duration in milliseconds public uint16 template_size; // size of template in bytes log stored public sbyte error_code; // error code if enroll / verify failed public byte sensor_type; // sensor type connected device public byte unit_id; // unit id assigned device, same net id (get/set command net id bii_get_netid / bii_set_netid) public byte admin_level; // admin level of template log stored public byte rsz_3; /* reserved */ public byte rsz_4; /* reserved */ public byte rsz_5; /* reserved */ [marshalas(unmanagedtype.byvalarray, sizeconst = 16)] public byte[] ta_msg; /*f1,f2,f3,f4 key message */ }
now when call function using, generates accessviolationexception , shows following message: "attempted read or write protected memory. indication other memory corrupt."
int transactionscount=-1; bii_transaction_log_ex[] logs = new bii_transaction_log_ex[1000]; int result = gettransactionlogs(0, 0, ref transactionscount, ref logs);
i think i'm making mistak in marshelling struct involved, far i'm unable find out exact problem. appreciated..
edit: don't have c++ source code.
the c++ function declared so:
int bii_read_transaction_log_ex( int ioption, int iupdateflag, int *imaxentries, bii_transaction_log_ex *log );
the final parameter single struct, passed reference. in case c# be:
[dllimport(@"...", callingconvention=callingconvention.cdecl, entrypoint = "bii_read_transaction_log_ex")] public static extern int gettransactionlogs( int option, int updateflag, ref int maxentries, ref bii_transaction_log_ex transactionlogs );
note there no need unsafe here, removed it. , looks c++ function uses cdecl
.
however, use of plural in transactionlogs
, , maxentries
parameter makes me suspect c++ code expects array. in case write:
[dllimport(@"...", callingconvention=callingconvention.cdecl, entrypoint = "bii_read_transaction_log_ex")] public static extern int gettransactionlogs( int option, int updateflag, ref int maxentries, [out] bii_transaction_log_ex[] transactionlogs );
i'm sceptical of use of pack=1
in struct definition. made that. expect aligned struct in case should remove pack
. don't think matters since c++ struct puts reserved members in spaces padding added, i'd still rather see struct declared aligned.
Comments
Post a Comment