Jay

Jay

  • NA
  • 1
  • 0

marshalling unsafe structures in C#

Nov 23 2007 5:50 AM

I have a C function Do_Something(struct_A* obj) which I want to call from C#.

This take struct_A pointer as IN parameter. struct_A has array of struct_B whose size is variable.

‘C’ Structures and function are as below.

/*

C Code -------->

*/

struct struct_B

{

    int        m_num;      /* Number of items in m_dataArray */

    int        *m_dataArray;  /* size is m_num*/

};

 

 

struct struct_A

{

    int            type ; /* Some integer value*/

    struct_B*  m_array_Of_B; /*Pointer to struct_B structure*/

};

extern __declspec(dllexport) int Do_Something(struct_A* obj);

 

//<---------------

 

I have wrapped these structures in C# and I want to call Do_Something() from C# program.

 

//C# Code -------->//C# Code -------->

 

[Serializable]

public struct STRUCT_B

{

    public  int m_num;

    public  int [] m_dataArray;

};

 

[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]

internal struct _STRUCT_B

{

    public int m_num;

    public unsafe int * m_dataArray;

};

 

[Serializable]

public struct STRUCT_A

{

    public  int type;

    public  STRUCT_B [] m_array_Of_B;

};

[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]

public struct _STRUCT_A

{

    public  int type;

    public  IntPtr m_array_Of_B;

};

 

[DllImport("libTest.dll",CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi,EntryPoint="Do_Something")]

internal static extern int _DoSomething

(

    ref _STRUCT_A obj

};

public unsafe void DoSomething

(

    ref STRUCT_A obj    /* pointer to struct method_list */

)

{

    LOCAL_STRUCT_A=new _STRUCT_A();

    LOCAL_dataSize = Marshal.SizeOf( typeof(STRUCT_B ) );

    LOCAL_STRUCT_A.m_array_Of_B=Marshal.AllocHGlobal(LOCAL_dataSize*obj.m_array_Of_B.Length);

    byte *LOCAL_run = (byte *)IntPtr.Zero;

    LOCAL_run = (byte *)(LOCAL_STRUCT_A.m_array_Of_B);

    for( int LOCAL_i = 0; LOCAL_i < obj.m_array_Of_B.Length; LOCAL_i++ )

    {

        Marshal.StructureToPtr(obj. m_array_Of_B[LOCAL_i], (IntPtr)LOCAL_run, false);

        LOCAL_run = LOCAL_run + LOCAL_dataSize;

    }

    _DoSomething(LOCAL_STRUCT_A);

}

//C# Code <--------

 

 

I am using Marshal.StructureToPtr to convert m_array_Of_B in STRUCT_A to IntPtr in _STRUCT_A and pass _STRUCT_A to DoSomething().

Everything works fine but when I debug in ‘C’ Dll values in m_dataArray in STRUCT_B are grabage.

Which means Marshal.StructureToPtr() converts STRUCT_B into IntPtr but it fails to preserve m_array_Of_B in STRUCT_B.

 

Has anybody face such a problem…………… Pleae reply as soon as possible.

Also it would be nice help if you could give me pointers in marshalling structures.

 

Thanks,

 

Jay