How can I correctly convert these to c#, marshall so I can pass these struct to DLL (c++)? -


c++

#define field_size_msgid       24 #define field_size_time        12 #define field_size_admin      256   typedef struct  {        char msgid[field_size_msgid+1];        char sendtime[field_size_time+1];        char receipttime[field_size_time+1];   } admindatam0;      typedef struct  {        int type;        union        {           admindatam0 m0;          char data[field_size_admin + 1];             } addata;         char unknown[field_size_admin + 1];   } admindata; 

c#:

    [dllimport("receiver.dll",         callingconvention = callingconvention.cdecl,          exactspelling = false,          setlasterror = false,          charset = charset.ansi,         entrypoint = "sendmessage")]     [return: marshalas(unmanagedtype.i4)]     protected static extern int sendmessage(         [marshalas(unmanagedtype.struct)] ref admindata ptradmindata, );      protected const int32 field_size_msgid = 24;    protected const int32 field_size_time = 12;    protected const int32 field_size_admin = 256;     [structlayout(layoutkind.sequential, charset = charset.ansi, pack = 1)]     public struct admindatam0     {         [marshalas(unmanagedtype.byvalarray, sizeconst = field_size_msgid + 1)]         public char[] msgid;          [marshalas(unmanagedtype.byvalarray, sizeconst = field_size_time + 1)]         public char[] sendtime;          [marshalas(unmanagedtype.byvalarray, sizeconst = field_size_time + 1)]         public char[] receipttime;     }  [structlayout(layoutkind.sequential, charset = charset.ansi, pack = 1)]  protected struct admindata {      [marshalas(unmanagedtype.i4)]      public int32 ntype;       [marshalas(unmanagedtype.struct)]      public data admindata_data;                   [structlayout(layoutkind.sequential, charset = charset.ansi, pack = 1)]      public struct data      {          [fieldoffset(0)]          [marshalas(unmanagedtype.struct)]          public admindatam0 m0; //135           [fieldoffset(0)]          [marshalas(unmanagedtype.byvalarray, sizeconst = field_size_admin + 1)]          public char[] data_fldsizeadmin;                      }      [marshalas(unmanagedtype.byvalarray, sizeconst = field_size_admin + 1)]      public char[] unknown;  } 

main:

admindata oadmindata = new admindata();  oadmindata.admindata_data = new oadmindata.data();             oadmindata.admindata_data.m0 = new oadmindatam0();  oadmindata.admindata_data.m0.msgid = new char[field_size_msgid + 1];                                  oadmindata.admindata_data.m0.sendtime = new char[field_size_time + 1];                              oadmindata.admindata_data.m0.receipttime = new char[field_size_time + 1]; oadmindata.admindata_data.data_fldsizeadmin = new char[field_size_admin + 1]; oadmindata.unknown = new char[field_size_admin + 1];  string m0_msgid = "msgid"; string m0_sendtime = "send time"; string m0_receipttime = "receipttime"; string unknown =  "unknown";  m0_msgid.tochararray().copyto(oadmindata.admindata_data.m0.msgid, 0); m0_sendtime.tochararray().copyto(oadmindata.admindata_data.m0.sendtime, 0);                 m0_receipttime.tochararray().copyto(oadmindata.admindata_data.m0.receipttime, 0);   // function dll  sendmessage(ref oadmindata); 

problem:

only msgid , datadata_fldsizeadmin have values same value. think it's because sharing same memory address.

unknown, sendtime , receiptime don't have values.

in stead of marshalas[unmanagedtype.byvalarray], should use mashalas[unmanagedtype.byvaltstr] inside declaration of struct:

as in:

... public struct admindatam0 {     [marshalas(unmanagedtype.byvaltstr, sizeconst = field_size_msgid + 1)]     public string msgid;      [marshalas(unmanagedtype.byvaltstr, sizeconst = field_size_time + 1)]     public string sendtime;      [marshalas(unmanagedtype.byvaltstr, sizeconst = field_size_time + 1)]     public string receipttime; } ... 

see documentation:

byvaltstr: used in-line, fixed-length character arrays appear within structure. character type used byvaltstr determined system.runtime.interopservices.charset argument of system.runtime.interopservices.structlayoutattribute applied containing structure. use marshalasattribute.sizeconst field indicate size of array.

.net framework byvaltstr types behave c-style, fixed-size strings inside structure (for example, char s[5]). behavior in managed code differs microsoft visual basic 6.0 behavior, not null terminated (for example, mystring string * 5).

the documentation ´byvalarray´ sais (emphasis mine):

when marshalasattribute.value set byvalarray, sizeconst must set indicate number of elements in array. the arraysubtype field can optionally contain unmanagedtype of array elements when necessary differentiate among string types. can use unmanagedtype on array appear fields in structure.

so think code work using byvalarray, should add arraysubtype of lpstr marshalas attribute.


Comments

Popular posts from this blog

python - Scipy curvefit RuntimeError:Optimal parameters not found: Number of calls to function has reached maxfev = 1000 -

c# - How to add a new treeview at the selected node? -

java - netbeans "Please wait - classpath scanning in progress..." -