.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

Popular posts from this blog

php - Calling a template part from a post -

Firefox SVG shape not printing when it has stroke -

How to mention the localhost in android -