尝试从 QBuffer 上传数据时出现分段故障错误

问题描述 投票:0回答:1

我从未使用 C++ 或 Qt 进行编码,但我想自定义 Flameshot 以将图像上传到我的自托管 Picsur 实例。然而,Picsur 通过 api 上传图像的方法与 Flameshot 最初上传到的 Imgur 不同。

我确实弄清楚了如何发出http请求,并且我有完全可以工作的代码,但我的问题是,为了使其工作,我必须将 QPixmap 保存到一个文件中,然后上传该文件,该文件可以工作,但不能真的很有效率。

在保存然后上传文件之前我尝试的是直接使用 QBuffer 作为 http 请求的主体设备,但是当我执行该操作时,我会在控制台中收到此错误:

18344 Segmentation fault      (core dumped)
。我无法找到任何其他错误,包括将变量
QT_LOGGING_RULES
设置为
"*.debug=true"

这是我通过保存文件来工作的功能代码:

QByteArray byteArray;
QBuffer buffer(&byteArray);
buffer.open(QIODevice::WriteOnly);
pixmap().save(&buffer, "PNG");
buffer.close();

QSaveFile saveFile("tmp.png");
saveFile.open(QIODevice::WriteOnly);
saveFile.write(byteArray);
saveFile.commit();

QFile *file = new QFile("tmp.png");
file->open(QIODevice::ReadOnly);

QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image\"; filename=\"" + FileNameHandler().parsedPattern() + "\""));
filePart.setBodyDevice(file);
file->setParent(multiPart);
multiPart->append(filePart);

QUrl url(QStringLiteral("https://example.org/api/image/upload"));
QNetworkRequest request(url);
request.setRawHeader("Authorization",
                        QStringLiteral("Api-Key %1")
                        .arg(ConfigHandler().uploadClientSecret())
                        .toUtf8());

m_NetworkAM->post(request, multiPart);

这是引发分段错误的代码:

QByteArray byteArray;
QBuffer *buffer = new QBuffer(&byteArray);
buffer->open(QIODevice::WriteOnly);
pixmap().save(buffer, "PNG");
buffer->seek(0);

QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image\"; filename=\"" + FileNameHandler().parsedPattern() + "\""));
filePart.setBodyDevice(buffer);
multiPart->append(filePart);

QUrl url(QStringLiteral("https://example.org/api/image/upload"));
QNetworkRequest request(url);
request.setRawHeader("Authorization",
                        QStringLiteral("Api-Key %1")
                        .arg(ConfigHandler().uploadClientSecret())
                        .toUtf8());

m_NetworkAM->post(request, multiPart);

函数

pixmap()
返回 QPixmap,其中保存了 Flameshot 截图中的图像数据。
m_NetworkAM
是来自如下定义的类的变量:

m_NetworkAM = new QNetworkAccessManager(this);
connect(m_NetworkAM,
        &QNetworkAccessManager::finished,
        this,
        &ImgurUploader::handleUpload);

为了完整起见,这里是来自 Flameshot 的原始代码:

QByteArray byteArray;
QBuffer buffer(&byteArray);
pixmap().save(&buffer, "PNG");

QUrlQuery urlQuery;
urlQuery.addQueryItem(QStringLiteral("title"), QStringLiteral(""));
QString description = FileNameHandler().parsedPattern();
urlQuery.addQueryItem(QStringLiteral("description"), description);

QUrl url(QStringLiteral("https://api.imgur.com/3/image"));
url.setQuery(urlQuery);
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader,
                    "application/application/x-www-form-urlencoded");
request.setRawHeader("Authorization",
                        QStringLiteral("Client-ID %1")
                        .arg(ConfigHandler().uploadClientSecret())
                        .toUtf8());

m_NetworkAM->post(request, byteArray);

整个文件可以在这里查看:imguruploader.cpp

正如我所说,我对 C++ 和 Qt 都是全新的,所以我完全有可能在这里犯了一个完全明显的错误。

c++ qt file http qbuffer
1个回答
0
投票

我现在直接通过函数

QByteArray
使用
setBody
解决了这个问题。非常感谢@IgorTandetnik 指出了这一点!

这是功能代码:

QByteArray byteArray;
QBuffer *buffer = new QBuffer(&byteArray);
buffer->open(QIODevice::WriteOnly);
pixmap().save(buffer, "PNG");
buffer->close();

QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image\"; filename=\"" + FileNameHandler().parsedPattern() + "\""));
filePart.setBody(byteArray);
multiPart->append(filePart);

QUrl url(QStringLiteral("https://example.org/api/image/upload"));
QNetworkRequest request(url);
request.setRawHeader("Authorization",
                        QStringLiteral("Api-Key %1")
                        .arg(ConfigHandler().uploadClientSecret())
                        .toUtf8());

m_NetworkAM->post(request, multiPart);
© www.soinside.com 2019 - 2024. All rights reserved.