structure layout


i have use following structure using dllimport
typedef struct {
    long tpye;   
    lt l;     
    int       nl;     
    char      *kl;     
    int       kll;  
    bc1 bcl;    
    bc2 bch;    
} m;
lt,bc1,bc2  are enum. how above should be marshalled?
what 

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

Popular posts from this blog

BizTalk Server 2013 Azure VM Log Shipping and HA for hosts

Azure DocumentDB Owner resource does not exist

SQL Server 2008 - High Memory Usage