交叉拱上的字节填充问题

时间:2011-09-06 06:23:19

标签: c++ c cross-platform padding named-pipes

我注意到我的程序结构上的sizzeof()在x86和x64平台上是不同的。这是因为字节填充。由于一个要求(我的应用程序在交叉拱形m / c之间进行交谈),我需要确保目标应该获得与发送者通过nammedpipe发送的结构相同的大小(在我的情况下,我无法再次读取管道剩余数据..)。如果我可以在该结构上使用sizeof()运算符之前安全地禁用/启用填充或剥离填充字节,我需要一种C ++方式。

谢谢..

[编辑|结论]:只是其他人试图寻求类似问题的解决方案的输入。尝试了很多愚蠢的事情来解决这个问题,但是这里提到的一个可能的解决方案以另一种方式创建了问题,调试了哪个时间。我能找到的这个问题的最佳选择是使用序列化和反序列化方法,如下面提到的“R ..”。

5 个答案:

答案 0 :(得分:4)

避免编写使用struct / union的sizeof的代码。为了便于携带,请在单个成员上使用sizeof:

const int struct_size = sizeof(x.member1) + sizeof(x.member2) + ...;

答案 1 :(得分:4)

如果在结构之前键入#pragma pack(1),则应禁用填充。这适用于visual studio和gcc。您可能还希望使用#pragma pack(push)和#pragma pack(pop)来保存和恢复以前的填充规则。 例如:

#pragma pack(push)
#pragma pack(1)
struct
{
...
};
#pragma(pop)

答案 2 :(得分:2)

您使用的是什么编译器?您可以使用GCC的packed属性来告诉编译器不要在结构中添加任何填充。其他编译器可能具有类似的功能。

http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html

aligned属性也可以为您提供帮助。

答案 3 :(得分:2)

请记住还要确保使用与拱形无关的结构元素 - 如果两个不同的arch具有 - 比如说 - 不同的int大小,那么删除填充将无济于事。尝试使用stdint.h类型,例如。 int32_t而不是int。

答案 4 :(得分:1)

其他人已经指出,除了填充之外,类型的大小可能因架构而异。除此之外,字节顺序也可能不同(不是在32位和64位英特尔之间,但如果其他人被抛出则可能是一个问题)。

所以序列化是一个好主意。基本上只是为每个架构创建一个写入功能和一个读取功能。

write函数将写入每个结构成员的每个相关字节,其中成员以已知顺序编写,并且每个成员的字节也按已知顺序(例如,最重要的第一个)。如果类型的大小因平台而异,请写入所有平台将支持的类型的字节数。

读取函数应该与写入函数的作用相反,并且将序列化数据中未包含的任何字节归零。这些函数并不难写,使用它们会使填充,字节序和基本类型的(通常)大小无关。