5

我正在学习 C 中的结构填充和打包。我有这个疑问,因为我已经阅读过填充将取决于架构,所以它会影响机器间通信吗?,即。如果在一台机器上创建的数据正在另一台机器上读取。在这种情况下如何避免这个问题。

4

5 回答 5

6

是的,您不能在平台之间发送结构的二进制数据并期望它在另一端看起来相同。

你解决它的方法是你为你的构造创建一个编组器/解组器,并在离开一个系统的路上传递它,并在进入另一个系统的路上。这使编译器可以在每个系统上为您处理缓冲。

每一方都知道如何获取数据,正如您指定的那样,它将被发送,并为本地平台处理它。

诸如 java 之类的平台通过为您的类创建序列化机制来为您处理这个问题。在 C 中,您需要自己执行此操作。你如何做取决于你想如何发送你的数据。您可以序列化为二进制、XML 或其他任何内容。

于 2013-05-07T02:35:00.350 回答
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

于 2013-05-07T02:33:40.340 回答
1

在 C/C++ 中,结构被用作数据包。它不提供任何数据封装或数据隐藏功能(C++ 案例是一个例外,因为它与类的语义相似)。

由于各种数据类型的对齐要求,结构的每个成员都应该自然对齐。结构的成员按递增顺序分配。

于 2014-08-25T11:02:18.707 回答
0

只有当您为其他架构编译的代码使用不同的填充方案时,它才会受到影响。

为了帮助缓解问题,我建议您打包没有填充的结构。char reserved[2]如果需要填充,请在(例如)中使用占位符。另外,不要使用位域!!它们不是便携式的。

您还应该注意其他与架构相关的问题。特别是字节序和数据类型大小。如果您需要更好的可移植性,您可能希望对字节流进行序列化和反序列化,而不是将其转换为struct.

于 2013-05-07T02:43:05.410 回答
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;这包括描述一些架构独立的网络数据包。

于 2013-05-07T23:42:59.470 回答