编组C Struct,其中包含结构数组

我在这个论坛中提到了类似的问题,但没有得到我的问题的解决方案。

我一直在努力解决编组问题。 我有一个包含另一个结构数组的结构,该平台是Win CE 。 我使用的是Visual Studio 2008和.NET CF 3.5。

代码:

C结构:

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; 

结构MY_SUPPORTED_DATA_RATES的大小在C中296个字节

这是我尝试将其转换为C#结构:

C#转换:

  [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; }; 

在这里,我使用Marshal.SizeOf(my_supported_rates);获得304字节的大小Marshal.SizeOf(my_supported_rates);

我没有成功地尝试了以下事情:

  • 在my_supported_rates结构中添加和删除MarshalAs属性中的各种attrubute元素,例如ArraySubType = UnmanagedType.Struct
  • 我有Intptr所需的数据,我尝试使用代码my_supported_rates = (my_supported_rates) Marshal.PtrToStructure(ptr,my_supported_rates.GetType());将ptr转换为struct my_supported_rates = (my_supported_rates) Marshal.PtrToStructure(ptr,my_supported_rates.GetType()); 。 但是没有适当的转换。
  • 关于博客和StackOverflow的一些其他建议对我来说并不是很有用

你的翻译对我来说很好。 在桌面而不是CE上运行我发现,对于这些类型

 [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; }; 

 Marshal.SizeOf(typeof(my_supported_rates)) == 296 

所以在CE pinvoke marshaller中似乎有些奇怪。 你可能需要通过这样做来强制marshaller的手:

 [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; }; 

也就是说,如果CE支持LayoutKind.ExplicitFieldOffset

如果他们不受支持,那么你需要手工编组。 您正在寻找Marshal.AllocHGlobal ,然后是Marshal.ReadByteMarshal.ReadInt16等等。