【发布时间】:2014-10-29 22:01:38
【问题描述】:
我是一名 C# 开发人员,正在为用 C++ 编写的服务器编写客户端。服务器通过 TCP/IP 将一些任意数据流式传输到客户端,我们必须在另一端重新组装它。服务器首先向我们发送数据的描述,然后是数据本身。
有问题的结构:
struct Inner_S
{
double a;
double b[4][4];
};
#pragma pack(1)
struct Packed_S
{
uint8_t c;
Inner_S d;
};
服务器告诉客户端外部结构对齐为 1,内部结构对齐为 8。协议规范说:
流式结构中的字段对齐是根据 Itanium 64 位 C++ 应用程序二进制接口规范完成的(即与典型 64 位平台上的典型 GNU 编译器相同)。
我找到了Itanium 64-bit C++ Application Binary Interface specification。我认为我正在寻找的部分是“虚拟基地以外的成员分配”,但我迷路了。
在 C# 方面,我正在读取数据流并将我自己的类与从结构中提取的值打包在一起。我需要知道在流中的确切位置来查找结构的每个元素。
我目前正在以这种方式处理结构,据我的用户说这是错误的:
(以对齐 1 开始结构)(无需填充)(读取简单值)c(以对齐 8 开始内部结构)(将填充添加到对齐 8)0000000(读取字段)aaaaaaa(开始数组)(读取简单值)bbbbbbbb.....
at least one site.支持该方法
那么,当我解析这些数据时,如何处理Inner_S 中的对齐?
caaaaaaaabbbbbbbb....(我想?) caaaaaaaa0000000bbbbbbbb....(看起来不对)
【问题讨论】:
-
你知道,一个简单的 C++ 程序打印出
sizeof你的类型和offsetof你的每个字段将帮助你更快地调试这种事情! :-) -
这是个好主意。
-
通过实验确定这一点的一个问题是它的完成方式是编译器特定的,它不是语言特性。我想如果我在不同的平台上使用 GCC,它会以相同的方式工作,但我不确定?
-
客户抱怨的特定问题已通过从结构的开头而不是从任何类型的全局引用进行对齐来解决,并在结构的末尾添加填充而不是让它成为容器立即恢复对齐控制。这仍然不是对应该发生的事情的简洁和完整的描述,并且导致内存布局否定了内部结构的点,其中包含 8 个包。
标签: c++ structure memory-alignment