我正在学习C中的结构填充和包装。 我有这个疑问,因为我读取填充将取决于体系结构,它是否会影响机器间通信?,即。如果在一台机器上创建的数据正在其他机器上读取。 在这种情况下如何避免此问题。
答案 0 :(得分:6)
是的,您无法在平台之间发送结构的二进制数据,并希望它在另一侧看起来相同。
你解决它的方法是为你的构造创建一个marshaller / demarshaller,并在从一个系统出来的路上传递它,然后进入另一个系统。这使编译器可以在每个系统上为您进行缓冲。
每一方都知道如何获取数据,因为您已指定将其发送,并为本地平台处理数据。
像java这样的平台通过为您的类创建序列化机制来为您处理。在C中,你需要自己做这件事。如何操作取决于您希望如何发送数据。您可以序列化为二进制,XML或其他任何内容。
答案 1 :(得分:2)
#pragma pack
。这可以允许程序员为结构指定所需的填充方法。
http://msdn.microsoft.com/en-us/library/2e70t5y1%28v=vs.80%29.aspx
http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html
http://clang.llvm.org/docs/UsersManual.html#microsoft-extensions
答案 2 :(得分:1)
在C / C ++中,结构用作数据包。它没有提供任何数据封装或数据隐藏功能(C ++案例因其与类的语义相似性而异常)。
由于各种数据类型的对齐要求,结构的每个成员都应该自然对齐。结构成员按顺序递增顺序。
答案 3 :(得分:0)
只有为其他架构编译的代码使用不同的填充方案时才会受到影响。
为了帮助缓解问题,我建议您打包没有填充的结构。在需要填充的地方,使用占位符(例如char reserved[2]
)。另外,不要使用位域!!它们不便携。
您还应该了解其他与架构相关的问题。特别是字节序和数据类型大小。如果您需要更好的可移植性,您可能希望序列化和反序列化字节流,而不是将其作为struct
投射。
答案 4 :(得分:0)
您可以在结构声明之前使用#pragma pack(1),之前使用#pragma pack()来禁用基于体系结构的打包;这将解决问题的一半'因为一些数据类型也是基于体系结构的,为了解决后半部分,我通常使用特定的数据类型,如int_16为16位整数,u_int_32为32位整数,等等。
看看http://freebsd.active-venture.com/FreeBSD-srctree/newsrc/netinet/ip_icmp.h.html;这包括描述一些独立于架构的网络数据包。