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

我有一个要创建的文件的标头(我正在用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

===============>>#1 票数:2 已采纳

如@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

  ask by Nick Cullen translate from so

未解决问题?本站智能推荐:

2回复

C ++将不同的数据类型打包成一个长变量

我陷入了陷阱,试图将一些变量打包成一个8字节长的变量。 基本上,我有一些具有小二进制大小的短项目,我需要将它们打包在一起发送到必须能够将其拆除的类中。 所以我做了以下几点: 然后我创建一个PACKAGE类型的变量,它是空的(0) 我想使用二进制操作将变量抛入该包中,我
2回复

C / C ++结构打包不起作用

我正在尝试在 64位 32位Windows上使用g ++打包结构。 输出8。我尝试过的其他方法: 因此,似乎结构已打包,但在某些情况下将sizeof取整? (实际上,写完这个问题后,我想我可以回答,但我还是会把它张贴在后人身上。) 编辑:其实我不知道。
6回复

C / C ++将signed char打包成int

我需要将四个带符号的字节打包成32位整数类型。 这就是我的目标: 这是一个很好的解决方案? 它是便携式的(不是通信意义上的)吗? 是否有现成的解决方案,或许可以提升? 问题我最关心的是将负位从char转换为int时的位顺序。 我不知道应该是什么样的正确行为。 谢谢
5回复

打包32位浮点数为30位(c ++)

以下是我要实现的目标: 我需要将32位IEEE浮点数打包成30位。 我想通过将尾数的大小减少2位来实现这一点。 操作本身应该尽可能快。 我知道会丢失一些精度,这是可以接受的。 如果这个操作不会破坏像SNaN,QNaN,无穷大等特殊情况,那将是一个优势。但
1回复

用Python打包和用C解包

我试图将整数作为字节打包在python中,并在C中解压缩它们。所以在我的python代码中,我有类似 它将10打包为一个字节,并在我的C代码中调用函数“ process”。 我需要在C代码中解压缩此打包数据吗? 也就是说,我该怎么做才能从给定的打包数据中取回10。
1回复

python tkinter包装

有人可以解释一下为什么当您将一个简单的小部件作为一行A起作用时 但是,当您为其命名或附加命令时,代码A不再起作用,并显示错误消息B 并且必须使用单独的行包装? 代码A 错误讯息B
2回复

打包位图

我正在尝试将字体字形图像打包到单个纹理中。 位图是每个像素单色1个字节,我希望将它们全部打包到1个纹理上。 我能够计算所需的最小纹理大小,但无法管理将它们打包在一起的算法。 我目前将位图存储为char指针,并且能够获取每个位图的尺寸。
3回复

由于填充C(gcc / g ++)计算开销

由于打包,我想计算/总结一个目标文件的开销(理想情况下,让gcc最小化它)。 例如,考虑以下结构(32位x86,gcc): 虽然实际数据只占用6个字节,但该结构在内存中占用12个字节,因为两个字符后跟3个填充字节。 通过重新排序结构如下: 该结构只有sizeof(stru
1回复

打包字典

显然,我在这里错过了一些很简单的事情,但是我找不到答案。 问题是为什么代码: 给出1(1、2、3) 而 给出1 {}而不是1 {'arg2_1':1,'arg2_2':2,'arg2_3':3}。 我如何打包和解压缩字典,而不必在函数定义或函数调用上都写所有字典
3回复

网络数据打包

我正在寻找一种有效地打包数据以便通过网络发送数据的方法。 我发现了一个建议方法的主题: http : //www.sdltutorials.com/cpp-tip-packing-data 而且我也看到了它在商业应用中的使用。 因此,我决定尝试一下,但结果却出乎我的意料。 首