Python打包int32但不起作用?

2024-04-28 22:57:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我干了一整天,似乎找不到解决办法:(

<>我有一个文件要创建的头(我在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个字节,是吗?在

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

^{pr2}$

“顶点”大小正确设置为56,但“顶点”数量设置为65536。如果我把它的数据类型改为uint16(unsigned short),它就会被正确地设置为36。但为什么呢? 我正在使用pack("<I")函数(知道我的机器是little-endian)。在

这是我用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))

遵循结构包函数(https://docs.python.org/2/library/struct.html)。。。H是unsigned short(2字节),I是unsigned integer(4字节),H是short(2字节),与我在C MeshHeader类中指定的完全匹配,不是吗?在

在过去的几个小时里,我一直在拔头发(我的头发已经不剩了!)。有什么建议吗?在

下面是Sublime Text 3 btw中的头文件快照 http://gyazo.com/e15942753819e695617390129e6aa879


Tags: self字节countpositiontangentuvpackoffset
1条回答
网友
1楼 · 发布于 2024-04-28 22:57:48

正如@martineau提到的,你看到的是C struct packing。编译器在非字大小的成员之间添加填充以优化内存访问。您可以使用某些#pragma指令来禁用它。对于visualc,语法是#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)

请注意,即使避免了struct packing,您仍然可能对endianity有问题。将结构写入磁盘假定您在编写器和读卡器之前拥有完全的控制权和知识。使用适当的序列化库可以使您的生活更轻松。有很多,但是支持C和Python的例子有protobuf和{a5}。在

相关问题 更多 >