简体   繁体   English

从struct到std :: vector的二进制复制数据

[英]binary copy data from struct to std::vector

I am using a lib which can load BMP images from memory. 我正在使用可以从内存加载BMP图像的库。

I have a class which represents a BMP. 我有一个代表BMP的课程。

To load from memory I have to supply a pointer to some BMP formatted data in memory and a variable for the size of that data. 要从内存加载,我必须提供指向内存中一些BMP格式数据的指针,以及该数据大小的变量。 (void* data, size_t length)

I want to store my data in a std::vector . 我想将数据存储在std::vector (Avoids manual memory management) (避免手动内存管理)

I've attempted to write a function to return a std::vector<unsigned char> , but I don't think what I've got is very good. 我试图编写一个返回std::vector<unsigned char>的函数,但我认为我所获得的不是很好。

std::vector<unsigned char> BMP::BITMAP::SaveMem() const
{

    // memory storage
    std::vector<unsigned char> memory;


    BITMAPFILEHEADER f_head;
    f_head.bfType = ushort_rev(((WORD)'B' << 0x08) | ((WORD)'M' << 0x00));
    f_head.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + m_width_memory * m_height;
    f_head.bfReserved1 = 0;
    f_head.bfReserved2 = 0;
    f_head.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);


    // build standard bitmap file header
    BITMAPINFOHEADER i_head;
    i_head.biSize = sizeof(BITMAPINFOHEADER);
    i_head.biWidth = m_width;
    i_head.biHeight = m_height;
    i_head.biPlanes = 1;
    i_head.biBitCount = m_bit_count;
    i_head.biCompression = 0;
    i_head.biSizeImage = m_width_memory * m_height;
    i_head.biXPelsPerMeter = 0;
    i_head.biYPelsPerMeter = 0;
    i_head.biClrUsed = 0;
    i_head.biClrImportant = 0;


    // alloc
    memory.resize(f_head.bfSize);

    std::copy(&f_head, &f_head + sizeof(f_head), memory.at(0));
    std::copy(&i_head, &i_head + sizeof(i_head), memory.at(0) + sizeof(f_head));


    // write data
    for(unsigned int y = 0; y < m_height; ++ y)
    {
        std::copy(&m_data[y * m_width_memory], m_data[y * m_width_memory + 3 * m_size_x], memory.at(0) + sizeof(f_head) + sizeof(i_head));
    }

}

Clearly this doesn't compile. 显然,这不能编译。 I can't think of any alternative to std::copy . 我想不出std::copy的任何替代方法。 Is this really the right tool for the job? 这真的是完成工作的正确工具吗?

To make it compile I think I should change memory.at(x) to memory.data() + x ... By doing this I would be using raw pointers - which is why I don't think std::copy is any better than memcpy . 为了使其编译,我认为我应该将memory.at(x)更改为memory.data() + x ...这样,我将使用原始指针-这就是为什么我认为std::copy存在任何原因比memcpy

Could I have some advice on this? 请问对此有何建议? It's somewhat an illogical task and had I known about this requirement earlier I would have stored my pixel data in an unsigned char with the bitmap file headers preceeding the data. 这有点不合逻辑,我早些时候就知道这一要求,所以我会将像素数据存储在一个unsigned char ,并且位图文件头位于数据之前。 Unfortunatly it will be a lot of work to change the design now, so I'd rather not touch it. 不幸的是,现在更改设计将需要大量工作,因此我宁愿不去尝试。

Three problems: 三个问题:

  1. You want to copy bytes , but the std::copy function is provided a pointer to a BITMAPFILEHEADER (or BITMAPINFOHEADER ) structure. 您想复制字节 ,但是std::copy函数提供了一个指向BITMAPFILEHEADER (或BITMAPINFOHEADER )结构的指针。 You need to convert the pointers to bytes , like reinterpret_cast<uint8_t*>(&f_head) . 您需要将指针转换为字节 ,例如reinterpret_cast<uint8_t*>(&f_head)

  2. The previous leads to other problems with the end of the data, the expression &f_head + sizeof(f_head) which really is equal to (&f_head)[sizeof(f_head)] , and is way beyond the end of the structure. 前面的问题导致了数据结尾的其他问题,表达式&f_head + sizeof(f_head)实际上等于(&f_head)[sizeof(f_head)] ,并且超出了结构末尾。 You need to use bytes here as well, as in reinterpret_cast<uint8_t*>(&f_head) + sizeof f_head . 您还需要在这里使用字节,例如reinterpret_cast<uint8_t*>(&f_head) + sizeof f_head

  3. The last problem is the destination for the std::copy call, as it needs to be a similar type as the source, ie a pointer to uint8_t (in the case of my casts). 最后一个问题是std::copy调用的目标,因为它需要与源相似,即指向uint8_t (对于我的演员来说)。 You can easily get that by doing eg &memory[0] . 您可以通过执行&memory[0]轻松地获得它。 And for the second call &memory[sizeof f_head] . 对于第二个调用&memory[sizeof f_head]

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

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