【问题标题】:Mapping byte array data to structs in C#将字节数组数据映射到 C# 中的结构
【发布时间】:2011-07-21 07:59:10
【问题描述】:

我已经为一个问题苦苦挣扎了太多小时,所以我转过来看看是否有人知道如何解决这个问题。 我有一个通过套接字发送数据包的遗留 C++ 程序。这些包含 C++ 结构,我认为在我的 C# 应用程序中定义一个看起来像 C++ 中的结构并读取字节数组会很容易。 我注意到它并不是那么简单,我认为我已经将问题归结为对齐,但我仍然无法理解它。

我的 C++ 结构如下所示:

typedef struct
{
    int                  int_1;
    short              short_1;
    long               long_1;
    char                char_11[11];
    long               long_2;
    short              short_2;
    int                  int_2;

} TEST_KLIENT_REC, *PTEST_KLIENT_REC;

我认为我可以翻译成这样的 C# 结构:

[StructLayout(LayoutKind.Explicit, Pack=0)]    
public struct TEST_KLIENT_REC
        {
            [FieldOffset(0)]
            [MarshalAs(UnmanagedType.I4)]
            public int          int_1;          // 4
            [FieldOffset(4)]
            [MarshalAs(UnmanagedType.I2)]
            public short        short_1;        // 2
            [FieldOffset(6)]
            [MarshalAs(UnmanagedType.I4)]
            public int          long_1;         // 4
            [FieldOffset(12)]
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=11)]
            public string       char_11;        // 11
            [FieldOffset(22)]
            [MarshalAs(UnmanagedType.I4)]
            public int          long_2;         // 4
            [FieldOffset(26)]
            [MarshalAs(UnmanagedType.I2)]
            public short        short_2;        // 2
            [FieldOffset(28)]
            [MarshalAs(UnmanagedType.I4)]
            public int          int_2;          // 4
        }

问题似乎是 C# 如何映射到 short(放入 2 个字节的填充?),这会导致结构的其余部分严重对齐并创建垃圾数据。 是否有可能以某种方式完成这项工作? 如果类更容易,我不会对在 C# 中使用结构感到困惑。

在使用一些测试数据时,结果似乎是 int_1、long_1 和 short_1 得到正确的值,而其他一切都是垃圾,这就是为什么我怀疑这里的问题是短。

欢迎提出任何想法。

/J

编辑:至于为什么我有 12 而不是 10 的字符串偏移量是因为如果我把 10 改为我认为应该的那样,char ararys 似乎必须从偶数 DWORD 开始(我知道我的数学谢谢你)我得到一个崩溃“无法从程序集'SocketAndStructTest,Version = 1.0.0.0,Culture = Neutral,PublicKeyToken = null'加载类型'TEST_KLIENT_REC',因为它包含偏移量10处的对象字段,该对象字段不正确地对齐或重叠一个非对象字段。”

【问题讨论】:

  • 6 + 4 != 12,只是说:) 至于检查,在 C/C++ 和 C# 中都执行 'sizeof' 并比较它们。
  • 我添加了一个编辑为什么我似乎不能使用更合乎逻辑的数字 10
  • 为什么不在 C# 结构中使用长类型来匹配 C++ 中的长类型?
  • 因为 C++ 中的 long 是四个字节长,在 C# 中转换为 Int32 (int)。

标签: c# c++ bytearray struct


【解决方案1】:

您的FieldOffsets 没有按照您的预期排列。例如,在两个 I_4 和一个 I_2 之后,你有 FieldOffset(12),而我认为你会想要 FieldOffset(10)

另外,我认为您需要将[StructLayout(LayoutKind.Explicit)] 应用于struct

【讨论】:

  • 是的,对于显式部分很抱歉,我只是忘记将它复制到问题文本中。关于 12 对 10,我对我的帖子做了一个简短的编辑。所以不要去那里。
猜你喜欢
  • 2010-09-05
  • 1970-01-01
  • 1970-01-01
  • 2011-04-22
  • 2013-11-11
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 2010-09-24
相关资源
最近更新 更多