我已经为一个问题苦苦挣扎了太多个小时,所以我转向这里看看是否有人知道如何解决这个问题。 我有一个遗留的 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 得到正确的值,而其他一切都是垃圾,这就是为什么我怀疑 short 是这里的问题。
欢迎任何想法。
/J
编辑:至于为什么我有 12 而不是 10 的字符串 Offset 是因为它似乎 char ararys 必须以偶数 DWORD 开始,如果我把 10 放在我认为应该的位置(我知道我的数学谢谢你)我遇到了“无法从程序集‘SocketAndStructTest,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null’加载类型‘TEST_KLIENT_REC’的崩溃,因为它在偏移量 10 处包含一个对象字段,该字段未正确对齐或重叠一个非对象字段。”
最佳答案
您的 FieldOffsets
没有按照您期望的方式排列。例如,在两个 I_4 和一个 I_2 之后,您有 FieldOffset(12)
,而我认为您需要 FieldOffset(10)
。
此外,我认为您需要将 [StructLayout(LayoutKind.Explicit)]
应用于 struct
。
关于c# - 将字节数组数据映射到 C# 中的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6772948/