2

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

我一直在努力解决编组问题。我有一个包含另一个结构数组的结构,平台是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;
    };

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

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

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

1 回答 1

3

你的翻译在我看来不错。在桌面而不是 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 中似乎有些奇怪。您可能需要通过执行以下操作强制编组器的手:

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

也就是说,如果LayoutKind.ExplicitFieldOffset在 CE 上受支持。

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

于 2014-04-09T14:28:44.933 回答