问题
I referred the similar questions in this forum but didn't get the solution for my problem.
I have been struggling with marshaling problem for a while. I have a structure that contains an array of another structure, The platform is Win CE. I am using Visual Studio 2008 and .NET CF 3.5.
The code:
C Structures:
struct dot11Rate
{
unsigned int rate;
unsigned char mode;
};
typedef struct my_supported_rates
{
unsigned short n_rates;
struct dot11Rate srates[36];
unsigned char isSet;
unsigned char no_of_HTStreams;
}MY_SUPPORTED_DATA_RATES;
Size of the struct MY_SUPPORTED_DATA_RATES is 296 bytes in C
This is my attempt to convert it into a C# struct:
C# Converted:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct dot11Rate
{
public uint rate;
public byte mode; /* HT=1, non-HT=0*////
};
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct my_supported_rates
{
public ushort n_rates;
[MarshalAs(UnmanagedType.ByValArray,SizeConst = 36)]
public dot11Rate[] srates;
public byte isSet;
public byte no_of_HTStreams;
};
Here I am getting the size as 304 bytes using Marshal.SizeOf(my_supported_rates);
I have tried the following things without any success:
- Adding and removing various attrubute elements in MarshalAs attribute in my_supported_rates struct such as
ArraySubType = UnmanagedType.Struct
- I have Intptr with required data and I tried to convert ptr to the struct using the code
my_supported_rates = (my_supported_rates) Marshal.PtrToStructure(ptr,my_supported_rates.GetType());
. But proper conversion is not happend. - Some other suggestions on blogs and StackOverflow which didn't prove useful to me
回答1:
Your translations look good to me. Running on desktop rather than CE I find that, for these types
[StructLayout(LayoutKind.Sequential)]
public struct dot11Rate
{
public uint rate;
public byte mode;
};
[StructLayout(LayoutKind.Sequential)]
public struct my_supported_rates
{
public ushort n_rates;
[MarshalAs(UnmanagedType.ByValArray,SizeConst = 36)]
public dot11Rate[] srates;
public byte isSet;
public byte no_of_HTStreams;
};
that
Marshal.SizeOf(typeof(my_supported_rates)) == 296
So it would seem to be something odd in the CE pinvoke marshaller. You might need to force the hand of the marshaller by doing this:
[StructLayout(LayoutKind.Explicit, Size=296)]
public struct my_supported_rates
{
[FieldOffset(0)]
public ushort n_rates;
[FieldOffset(4)]
[MarshalAs(UnmanagedType.ByValArray,SizeConst = 36)]
public dot11Rate[] srates;
[FieldOffset(292)]
public byte isSet;
[FieldOffset(293)]
public byte no_of_HTStreams;
};
That is, if LayoutKind.Explicit
and FieldOffset
are supported on CE.
If they are not supported then you'll need to marshal by hand. You are looking for Marshal.AllocHGlobal
and then Marshal.ReadByte
, Marshal.ReadInt16
and so on.
来源:https://stackoverflow.com/questions/22964241/marshalling-c-struct-with-array-of-structures-in-it