【发布时间】: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)。