我正在尝试通过 TCP 从 C(实际上是 Obj-C,但面向对象不在此等式)客户端向 python 服务器发送消息。现在我发送unsigned short
第一个消息大小,然后是消息,它是一个 C 结构。我想在包的末尾附加一个动态字符串,所以我决定使用结构大小将包一分为二,但问题开始了。
问题是,要么我做错了,要么 Python 的 struct 库大小 + 填充计算存在错误。
Python struct 似乎可以正确解析填充。例如,对于这个结构:
struct.Struct("H I").size == 8
sizeof
与此结构的返回值匹配:
#include <stdio.h>
typedef struct {
unsigned short a;
unsigned int b;
} test;
int main() {
printf("%ld\n", sizeof(test));
return 0;
}
$ gcc test.c
$ ./a.out
8
但是对于某些结构定义,我并不总是得到相同的结果。例如,在这种情况下:
struct.Struct("H 5s").size == 7
typedef struct {
unsigned short a;
char b[5];
} test;
sizeof(test) == 8
我在某处读到编译器可能会填充一个结构以确保在数组中使用结构时可以正确访问内存。我不确定是否是这种情况(似乎是),但如果是这样,我不明白为什么这个结构没有填充到 8 个字节(假设是 4 个字节的打包):
struct.Struct("H 4s").size == 6
typedef struct {
unsigned short a;
char b[4];
} test;
sizeof(test) == 6
因此,为了澄清,我的问题是如何在 Python 中获得给定结构的精确大小,因为它没有应用最终填充。
我试过的:
手动添加最终填充大小:
real_struct_size = self._struct.size + self._struct.size % 4
当然,这不起作用,因为单个成员结构不会添加填充,并且正如您在最后一种情况中看到的那样,它也不适用于小型结构(无符号短 + 字符 [4])。(也许我在这里过度简化了问题。也许这与小结构无关,而是与我无法识别的另一个因素有关。)
然后我打开了 Python 的 struct 库,看看我怎样才能知道需要多少个参数,所以我可以问它是否为 1,然后避免最后的填充,但是无法访问的s_len
属性PyStructObject
(参见 Python-2.7.5 /Modules/_struct.c:48) 这是存储打包参数数量的地方。
因此,作为一种解决方法,我在数据包的开头放置了一个偏移值,以了解额外/动态字符串的开始位置。
但我认为这里有一个错误(我的或来自 Python 的 struct 库)。无论哪种方式,如果是我,我真的需要知道我做错了什么,或者如果它是 Python 的库,我想报告这个问题。如果有人可以帮助我弄清楚这一点,我将非常感激。
所以,提前谢谢!对不起,很长的帖子:)