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

Azure DocumentDB Owner resource does not exist

job syspolicy_purge_history job fail in sqlserver 2008

Trying to register with public marketplace error with 'Get-AzureStackStampInformation'