繁体   English   中英

Python Packing int32但不起作用?

[英]Python Packing int32 but doesn't work?

我整天都在这里,似乎找不到解决方法:(

我有一个要创建的文件的标头(我正在用Python解析obj文件,以输出为要加载到我的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基本上是stdint.h的uint32_t的typedef。...因此,从这来看,前三个成员var分别是2个字节,4个字节,2个字节,是吗?

这就是我将其读入结构的方式

fread(&_header, sizeof(MeshHeader), 1, f);

_vertex_size正确设置为56,但_vertex_count正确设置为65536。如果我将其数据类型更改为uint16(无符号短),它将正确设置为36。但是为什么呢? 我正在使用pack("<I")函数(知道我的机器是低端字节序)。

这是我在python中的打包代码

    f.write(pack('<H', self._vertex_size))
    f.write(pack('<I', self._vertex_count))
    f.write(pack('<H', self._index_buffer_count))
    f.write(pack('<h', self._position_offset))
    f.write(pack('<H', self._position_component_count))
    f.write(pack('<h', self._uv_offset))
    f.write(pack('<H', self._uv_component_count))
    f.write(pack('<h', self._normal_offset))
    f.write(pack('<H', self._normal_component_count))
    f.write(pack('<h', self._tangent_offset))
    f.write(pack('<H', self._tangent_component_count))
    f.write(pack('<h', self._binormal_offset))
    f.write(pack('<H', self._binormal_component_count))
    f.write(pack('<h', self._colour_offset))
    f.write(pack('<H', self._colour_component_count))

遵循struct.pack函数的规范( https://docs.python.org/2/library/struct.html )... H是无符号的短整数(2个字节)I是无符号的整数(4个字节),h是一小段(2个字节)与我在C MeshHeader类中指定的内容完全匹配,不是吗?

在过去的几个小时中,我一直在拔头发(而且剩下的很多!)。 关于可能发生的事情有什么建议吗?

这是Sublime Text 3中头文件的快照, 网址为http://gyazo.com/e15942753819e695617390129e6aa879

如@martineau所述,您看到的是C struct包装 编译器在非字大小的成员之间添加填充以优化内存访问。 您可以使用某些#pragma指令禁用此功能。 对于Visual C,语法为#pragma pack(1)MSDN中所述 在下面的示例中,我还使用pushpop将装箱恢复到其先前的值。 正确打包对于有效访问内存很重要,因此更改它仅应保留给您写入磁盘的结构。

// 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)

请注意,即使避免了结构打包,您可能仍然会遇到endianity问题。 将结构写入磁盘时,假设您拥有作家和读者都拥有的全部控制权和知识。 您可以使用适当的序列化库来简化生活。 有很多但同时支持C和Python的示例是protobufAvro

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM