structure layout
hello s h1,
1. c++ , c# enums.
>> lt,bc1,bc2 are enum. how above should be marshalled?
1.1 enums in c++ integer types default. enums integer types in c# default. hence may translate them directly in c# c++ equivalents.
1.2 however, please read section 2 , other useful advise expounded below.
2. explicit declararion of enum type.
to sure of matching types, declare underlying type enums. e.g. :
c++ :
enum lt : int
{
lt_0 = 0,
lt_1 = 1,
lt_2 = 2,
lt_3 = 3
};
enum bc1 : int
{
bc1_0 = 0,
bc1_1 = 1,
bc1_2 = 2,
bc1_3 = 3
};
enum bc2 : int
{
bc2_0 = 0,
bc2_1 = 1,
bc2_2 = 2,
bc2_3 = 3
};
c#
enum lt : int
{
lt_0 = 0,
lt_1 = 1,
lt_2 = 2,
lt_3 = 3
};
enum bc1 : int
{
bc1_0 = 0,
bc1_1 = 1,
bc1_2 = 2,
bc1_3 = 3
};
enum bc2 : int
{
bc2_0 = 0,
bc2_1 = 1,
bc2_2 = 2,
bc2_3 = 3
};
3. ensure matching struct member pack alignment.
3.1 make sure struct member packing alignment c++ , c# code matches.
3.2 sure of this, set project properties necessary.
3.3 may use #pragma pack c++ struct , structlayout pack field c# struct, e.g. :
c++
#pragma pack(1)
typedef struct
{
long tpye;
lt l;
int nl;
char *kl;
int kll;
bc1 bcl;
bc2 bch;
} m;
c#
[structlayout(layoutkind.sequential, pack=1)]
struct m
{
public int32 tpye;
public lt l;
public int nl;
[marshalas(unmanagedtype.lpstr)]
public string kl;
public int kll;
public bc1 bcl;
public bc2 bch;
};
4. declare "kl" member string , use marshalas(unmanagedtype.lpstr) attribute.
4.1 may have noticed in section 3 above, have declared "kl" member in c# side string , decorated marshalasattribute. there other ways same thing simple way pass string struct member c# c++.
4.2 note in case, "kl" string passed c# code c++ code (via dllimport) cannot modified c++ code. it must treated read-only c++ code.
4.3 if "kl" modifiable, other techniques have used.
4.4 decorating "kl" follows :
[marshalas(unmanagedtype.lpstr)]
public string kl;
we indicate @ runtime, "kl", string type, is marshaled null-terminated ansi character string. matches c++ declaration "kl" struct member char*.
5. example code.
5.1 following sample code demonstrating usage of m struct :
[dllimport("sh1dll01.dll", callingconvention = callingconvention.stdcall)]
public extern static void test(m _m);
static void main(string[] args)
{
m _m;
_m.tpye = 1001;
_m.l = lt.lt_1;
_m.nl = 1003;
_m.kl = "hello world";
_m.kll = 1004;
_m.bcl = bc1.bc1_1;
_m.bch = bc2.bc2_1;
test(_m);
}
5.2 note @ runtime, ansi copy of c# string "hello world" (which unicode) made , address passed "kl" member of unmanaged c++ m struct.
- bio.
.NET Framework > Common Language Runtime Internals and Architecture
Comments
Post a Comment