Search code examples
c#c++arraylistcompact-frameworkmarshalling

Marshalling array of structures from c++ to c# in WinCE


I'm trying to Marshal the following structures from c++ to c# on a Windows CE program and compact framework 2.0. I'm having a lot of difficulties with the marshalling of strings.

I have this c++ code:

#define Console_Parameters_MAX 50

struct AllParameters {
  Parameter Parameters[Console_Parameters_MAX];
} ;

struct Parameter { 
  int Index;
  int Id; 
  char Value[20];
};

extern "C" {
   BOOL GetAllConsoleParameters(AllParameters *pItem);
}

and this are the corresponding c# code:

[StructLayout(LayoutKind.Sequential)]
public struct AllParameters {
  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
  public Parameter[] Parameters
}

[StructLayout(LayoutKind.Sequential)]
public struct Parameter {
  public int Index;
  public int Id;
  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
  public byte[] Value;
}

[DllImport("exemple.dll", SetLastError = true)]
public static extern bool GetAllConsoleParameters([MarshalAs(UnmanagedType.Struct)] ref AllParameters pItem);

and this is how I invoke it:

AllParameters item = new AllParameters();
if (AppAPI.GetAllConsoleParameters(ref item)) {
   var array = item.Parameters;
}

When I call the GetAllConsoleParameters I get exception NotSupportedException. I've tried many configurations but with no success.

Can anyone advise on how to achieve it?

Thanks in advance


Solution

  • following my solution, c++ code:

    /* - not used
    #define Console_Parameters_MAX 50
    
    struct AllParameters {
      Parameter Parameters[Console_Parameters_MAX];
    } ;
    */
    
    struct Parameter { 
      int Index;
      int Id; 
      char Value[20];
    };
    
    extern "C" {
       BOOL GetAllConsoleParameters(Parameter pItem[], int size);
    }
    

    and corresponding c# code:

    /* - not used
    [StructLayout(LayoutKind.Sequential)]
    public struct AllParameters {
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
      public Parameter[] Parameters
    }
    */
    
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct Parameter {
      public int Index;
      public int Id;
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
      public byte[] Value;
    }
    
    [DllImport("exemple.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool GetAllConsoleParameters([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1), Out] ConsoleParameter[] myStruct, int size);
    

    and code invoke:

    ConsoleParameter[] item = new ConsoleParameter[50];
    if (AppAPI.GetAllConsoleParameters(item, 50)) {
       var array = item;
    }
    

    thanks a lot for help