我正在从我的服务器向客户端发送信息,然后使用打包的结构再次返回(显然结构中有更多的数据)
#pragma pack(push, 1)
struct other_data_struct
{
int hp;
int wp;
char movetype;
}
struct PlayerStats
{
int playerID;
other_data_struct data;
bool friendly; //<-this one messes up how the others are going to be packed on the 2 systems
}
#pragma pack(pop)
适用于所有固定大小的变量,整数和字符甚至其他结构。
当使用gcc for Linux编译服务器并且使用MSVC for windows编译客户端时,布尔值不能正常工作...
我曾想过制作某种容器(即带有8个布尔get / set函数或类似函数的unsigned char),但它看起来像古怪的那样古怪。
有没有办法在Windows和Linux上'包装'包含布尔变量的结构完全相同,或者我应该咬酸苹果并为每个布尔值使用char?
答案 0 :(得分:2)
您可以使用Google Protocol Buffers而不是您自己的打包结构。或者你可以避免bool以避免不兼容。
如果我真的必须从你所处的位置开始并使它工作,我会用它中的结构制作一个小程序并开始尝试其他填充字段,直到我想出了一些看起来完全相同的东西。两个系统。
答案 1 :(得分:2)
无论何时在不同系统之间传输数据,都不应该依赖于这些系统如何表示内存中的数据,因为内存表示可能因处理器体系结构,编译器选项和许多其他因素而异。您应该使用一些库进行序列化,因为该库的作者已经将许多想法放入了您可能不感兴趣的各种问题中。
答案 2 :(得分:2)
在一般情况下,你不应该对结束,字段大小,结构包装等做出假设。对于一般应用或图书馆开发,做这种事情是不好的做法。
也就是说,我在嵌入式系统上经常做这种事情,其中1)内存(RAM和可执行ROM)是宝贵的资源,因此需要避免不必要的库2)我知道我的代码将只针对一个平台,3)不希望打包/打包的性能受到影响。即便如此,它可能不是一种“最佳”做法。
如果你意识到以这种方式做事的风险,我想你自己回答了这个问题。如果您想100%确定,请为布尔值定义自己的类型。还要注意,long
的大小在32位和64位平台之间有所不同。我通常坚持使用每个数字原语的“stdint.h”类型,这样你就知道你正在处理的是什么大小。
答案 3 :(得分:1)
为什么不在调用ntohl,htonl,ntohs,htons等时进行序列化。这样可以很好地转换字节序 - 这比你正在做的更安全一些。如果你使用结构,那么你需要更多地担心编译器相关的东西,而不是你使用已知大小的核心类型。
这些函数以网络字节顺序放置数据,这是通信设备之间网络传输的标准。其他网络程序员也会更好地理解您的代码以用于维护目的:)
答案 4 :(得分:1)
您可以尝试bitfields,这样您的压缩结构包含'int',但您的代码使用更节省空间的表示。
我认为位域有一些可怕的性能特征,所以如果你更关心访问时间而不是空间使用,它们可能不是你想要的。
答案 5 :(得分:1)
我不清楚问题是什么。 Windows和Linux都将bool
定义为单字节对象。
Windows 将BOOL
定义为int
,因此,如果您将BOOL
放在网上并将其作为bool
阅读(或者将bool
放在电线上并将其作为BOOL
读取)然后你就会遇到麻烦。这相对容易修复。
可能是Windows和Linux为false
和true
定义了不同的值(更有可能的是,他们同意false
是0
,但不同意用于true
的值;即使在网络编程之外,也可能包含bool
或true
的{{1}}个变量,如下所示。标准要求false
至少为一个字节,一个字节有两个以上的可能值。
是的,将您的bool
转换为bool
并通过网络发送 将正常工作。
注意:“unsigned char
或bool
”的“true
个变量”:
false