结构填充 [英] Struct Padding

查看:111
本文介绍了结构填充的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从一个文件中直接读取大块数据到一个结构体,但填充导致太多的数据被读取和数据未对齐。

I am trying to read chunks of data from a file directly into a struct but the padding is causing too much data to be read and the data to be misaligned.

我的代码:

结构

typedef unsigned char byte;

struct Header
{
    char ID[10];
    int  version;
};

struct Vertex //cannot rearrange the order of the members
{
    byte    flags;
    float   vertex[3];
    char    bone;
    byte    referenceCount;
};

我如何读取数据:

std::ifstream in(path.c_str(), std::ifstream::in | std::ifstream::binary);

Header header;
in.read((char*)&header.ID, sizeof(header.ID));
header.ID[9] = '\0';
in.read((char*)&header.version, sizeof(header.version));
std::cout << header.ID << " " << header.version << "\n";
in.read((char*)&NumVertices, sizeof(NumVertices));
std::cout << NumVertices << "\n";

std::vector<Vertex> Vertices(NumVertices);

for(std::vector<Vertex>::iterator it = Vertices.begin(); it != Vertices.end(); ++it)
{
    Vertex& v = (*it);
    in.read((char*)&v.flags, sizeof(v.flags));
    in.read((char*)&v.vertex, sizeof(v.vertex));
    in.read((char*)&v.bone, sizeof(v.bone));
    in.read((char*)&v.referenceCount, sizeof(v.referenceCount));
}

我试过: in.read *)& Vertices [0],sizeof(Vertices [0])* NumVertices); 但是这会产生不正确的结果,因为我相信是填充。

I tried doing: in.read((char*)&Vertices[0], sizeof(Vertices[0]) * NumVertices); but this produces incorrect results because of what I believe to be the padding.

还有:目前我使用C风格的转换,在这种情况下使用正确的C ++转换是什么,还是C风格的转换可以吗?

Also: at the moment I am using C-style casts, what would be the correct C++ cast to use in this scenario or is a C-style cast okay?

推荐答案

如果你以二进制形式写整个结构,你不需要读它,就像你单独存储每个变量一样。

If you're writing the entire structure out in binary, you don't need to read it as if you had stored each variable separately. You would just read in the size of the structure from file into the struct you have defined.

Header header;
in.read((char*)&header, sizeof(Header));

如果您始终在同一架构或同一台机器上运行,担心endian问题,因为你将以与应用程序读取它们相同的方式写出它们。如果您在一个架构上创建文件并希望它在另一个架构上可移植/可用,那么您将需要交换字节因此。我过去的做法是创建一个我自己的交换方法。 (例如Swap.h)

If you're always running on the same architecture or the same machine, you won't need to worry about endian issues as you'll be writing them out the same way your application needs to read them in. If you are creating the file on one architecture and expect it to be portable/usable on another, then you will need to swap bytes accordingly. The way I have done this in the past is to create a swap method of my own. (for example Swap.h)

Swap.h - This is the header you use within you're code

void swap(unsigned char *x, int size);

------------------

SwapIntel.cpp - This is what you would compile and link against when building for Intel

void swap(unsigned char *x, int size)
{
    return;   // Do nothing assuming this is the format the file was written for Intel (little-endian)
}

------------------

SwapSolaris.cpp -  This is what you would compile and link against when building for Solaris

void swap(unsigned char *x, int size)
{
    // Byte swapping code here to switch from little-endian to big-endian as the file was written on Intel
    // and this file will be the implementation used within the Solaris build of your product
    return;   
}

这篇关于结构填充的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆