Python打包int32,但不';不行?

Python打包int32,但不';不行?,python,c++,binary,packing,Python,C++,Binary,Packing,我整天都在做这件事,似乎找不到解决办法:( 我有一个文件要创建的头(我在Python中解析一个Objo文件,把它输入到我的C++游戏引擎中加载的二进制数据)。 这里是网格标题的C++定义 struct MeshHeader { unsigned short _vertex_size; uint32 _vertex_count; unsigned short _index_buffer_count; short _position_offset; unsig

我整天都在做这件事,似乎找不到解决办法:(

我有一个文件要创建的头(我在Python中解析一个Objo文件,把它输入到我的C++游戏引擎中加载的二进制数据)。

这里是网格标题

的C++定义
struct MeshHeader
{
    unsigned short _vertex_size;
    uint32 _vertex_count;
    unsigned short _index_buffer_count;
    short _position_offset;
    unsigned short _position_component_count;
    short _uv_offset;
    unsigned short _uv_component_count;
    short _normal_offset;
    unsigned short _normal_component_count;
    short _tangent_offset;
    unsigned short _tangent_component_count;
    short _binormal_offset;
    unsigned short _binormal_component_count;
    short _colour_offset;
    unsigned short _colour_component_count;
};
其中,uint32基本上是一个来自uint32的typedef,来自stdint.h。。。。 所以从这个判断,前三个成员变量分别是2字节,4字节,2字节,是吗

我就是这样把它读入结构的

fread(&_header, sizeof(MeshHeader), 1, f);
_vertex_size将正确设置为56,但vertex_count将设置为65536。如果我将其数据类型更改为uint16(无符号短),它将正确设置为36。但为什么?
我正在使用
pack(“”,正如@martineau提到的,您看到的是。编译器在非字大小的成员之间添加填充以优化内存访问。您可以使用某些
#pragma
指令禁用它。对于Visual C,语法是
#pragma pack(1)
如中所述。在下面的示例中,我还使用
push
pop
将打包恢复到其以前的值。正确的打包对于有效的内存访问非常重要,因此更改它应该只保留给写入磁盘的结构

// align on 1-byte
#pragma pack(push, 1)
struct MeshHeader
{
    unsigned short _vertex_size;
    uint32 _vertex_count;
    unsigned short _index_buffer_count;
    short _position_offset;
    // ...
};
// restore alignment
#pragma pack(pop)

请注意,即使避免了结构打包,您也可能在以下方面存在问题。将结构写入磁盘假定您在编写器和读取器之前拥有完全的控制权和知识。使用适当的序列化库可以使您的生活更轻松。支持C和Python的示例很多,但也有一些是和。

至于如何编译C++代码,在结构成员之间可能会添加额外的字节,以使它们在32位或64位边界上对齐,计算机可以比不对齐的那些更有效地读写。可能有编译器选项禁用这一点,例如“代码> - StructPack < /代码>……谢谢。回答!我已经使用visual studio 2013 community edition对32位和64位构建进行了尝试。两者都产生了我上面得到的相同结果。更改体系结构,尤其是更改为更大的字数,可能无法解决此问题。您需要显式修改结构的打包方式。我如何才能做到这一点?您是否打算我没有做python端还是C端?我只是在最后一个回答中遇到了这个问题!谢谢:)我只是强迫小endian确保它不是endian问题。我现在要删除它。谢谢:)另一个快速问题-如果我要做所有这些整数,我的问题会消失吗?(也就是说,我不需要担心背包推送/弹出和填充问题?)或者这会导致从32/64台机器移植的问题吗?它会离开32位,但可能停留在64位,其中对齐是8字节。你应该真正考虑<代码>原Buff或类似的东西。我想你甚至可以使用序列化的对象作为一个正常的结构,所以转换应该很容易。太棒了,谢谢大家!我明天会去看它们,花了一整天的时间写我的第10个obj加载器。我发誓,这是最后一个。我发誓,软件开发人员要担心的问题比填充设计要避免的结构更重要。在我管理的商店里,我们决定默认总是使用单字节填充(这意味着永远不要添加填充)如果有必要的话,我们会担心以后会优化内存访问,但事实并非如此。
// align on 1-byte
#pragma pack(push, 1)
struct MeshHeader
{
    unsigned short _vertex_size;
    uint32 _vertex_count;
    unsigned short _index_buffer_count;
    short _position_offset;
    // ...
};
// restore alignment
#pragma pack(pop)