【发布时间】:2021-02-11 16:02:53
【问题描述】:
我正在生成位图文件。该程序每次都会编译,但在某些时候取决于#include 的顺序,它给了我好的或损坏的 .bmp 文件。
它来自一个教程,所有文件都是here。
我的结构如下:
main.cpp
#include <iostream>
#include "Bitmap.h"
using namespace std;
int main() {
Bitmap bitmap(800, 600);
bitmap.write("test.bmp");
}
位图.h
#include <string>
#include <cstdint>
#include <memory>
using namespace std;
class Bitmap {
private:
int m_width{0};
int m_height{0};
unique_ptr<uint8_t[]> m_pPixels{nullptr};
public:
Bitmap(int width, int height);
bool write(string filename);
};
BitmapFileHeader.h
#include <cstdint>
using namespace std;
#pragma pack(2)
struct BitmapFileHeader {
char header[2] { 'B', 'M' };
int32_t fileSize;
int32_t reserved { 0 };
int32_t dataOffset;
};
BitmapInfoHeader.h
#include <cstdint>
using namespace std;
#pragma pack(2)
struct BitmapInfoHeader {
int32_t headerSize{40};
int32_t width;
int32_t height;
int16_t planes{1};
int16_t bitsPerPixel{24};
int32_t compression{0};
int32_t dataSize{0};
int32_t horizontalResolution{2400};
int32_t verticalResolution{2400};
int32_t colors{0};
int32_t importantColors{0};
};
位图.cpp
#include <fstream>
#include "Bitmap.h"
#include "BitmapInfoHeader.h"
#include "BitmapFileHeader.h"
using namespace std;
Bitmap::Bitmap(int width, int height): m_width(width), m_height(height), m_pPixels(new uint8_t[width * height * 3]{ }) {}
bool Bitmap::write(string filename) {
BitmapFileHeader fileHeader;
BitmapInfoHeader infoHeader;
fileHeader.fileSize = sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader) + m_width * m_height * 3;
fileHeader.dataOffset = sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader);
infoHeader.width = m_width;
infoHeader.height = m_height;
ofstream file;
file.open(filename, ios::out | ios::binary);
file.write((char *)&fileHeader, sizeof(fileHeader));
file.write((char *)&infoHeader, sizeof(infoHeader));
file.write((char *)m_pPixels.get(), m_width*m_height*3);
file.close();
return true;
}
现在在Bitmap.cpp 中,按照这个顺序,一切正常。当我更改顺序以使 #include <fstream> 排在最后时,它仍然编译没有错误,但会生成损坏的文件。BitmapInfoHeader.h 和 BitmapInfoHeader.h 只是持有一个结构,每个结构中都有一些 int32_t 变量,不要根本不使用fstream。
为什么会这样?
【问题讨论】:
-
可能是
Bitmap*.h头文件之一中的错误。 -
#pragma pack(2)如果在标准头文件之前包含将导致损坏,因为这将改变已构建(标准)库的布局。更改包装后应尽快将包装重置为默认值