Qt 5.6 alpha QtWebEngine.如何使用QWebEngineUrlRequestJob
Qt 5.6 alpha QtWebEngine. How work with QWebEngineUrlRequestJob?
我继承了QWebEngineUrlSchemeHandler。重新定义的方法请求已启动(QWebEngineUrlRequestJob*请求)
在我尝试调用QWebEngineUrlRequestJob::回复之后
例如
void CustomUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *request)
{
qDebug() << "CustomUrlSchemeHandler::requestStarted -->>> " << request->requestUrl();
QMimeDatabase HelpViewer;
QMimeType mt = HelpViewer.mimeTypeForUrl(request->requestUrl());
const QString mimeType = mt.name();
QByteArray arr = QString::fromStdString("<html><body>Hello world</body></html>").toUtf8();
QBuffer *buffer = new QBuffer(&arr, this);
buffer->open(QIODevice::ReadOnly);
request->reply(mimeType.toLatin1(), buffer);
return;
}
但是程序崩溃了。参见日志:
[1126/113403:FATAL:weak_ptr.cc(26)] Check failed: sequence_checker_.CalledOnValidSequencedThread(). WeakPtrs must be checked on the same sequenced thread.
Backtrace:
base::debug::StackTrace::StackTrace [0x11A78691+33] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbasedebugstack_trace_win.cc:205)
logging::LogMessage::~LogMessage [0x119CB2AF+63] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbaselogging.cc:544)
base::internal::WeakReference::Flag::IsValid [0x119FB75A+234] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbasememoryweak_ptr.cc:28)
base::internal::WeakReference::is_valid [0x119FB7B2+50] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbasememoryweak_ptr.cc:43)
base::WeakPtr<base::ObserverListBase<content::ServiceWorkerContextObserver> >::get [0x109EF57F+31] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbasememoryweak_ptr.h:204)
base::internal::InvokeHelper<1,void,base::internal::RunnableAdapter<void (__thiscall content::DownloadResourceHandler::*)(void)>,base::internal::TypeList<base::WeakPtr<content::DownloadResourceHandler> const &> >::MakeItSo [0x107B8ADB+11] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbasebind_internal.h:300)
base::internal::Invoker<base::IndexSequence<0>,base::internal::BindState<base::internal::RunnableAdapter<void (__thiscall content::DownloadResourceHandler::*)(void)>,void __cdecl(content::DownloadResourceHandler *),base::internal::TypeList<base::WeakPtr<c [0x107BAD0A+58] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbasebind_internal.h:346)
base::Callback<net::URLRequestContext * __cdecl(void)>::Run [0x1096CACF+47] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbasecallback.h:396)
base::debug::TaskAnnotator::RunTask [0x11A9580D+541] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbasedebugtask_annotator.cc:64)
base::MessageLoop::RunTask [0x119DAAF8+456] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbasemessage_loopmessage_loop.cc:475)
base::MessageLoop::DeferOrRunPendingTask [0x119D9204+52] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbasemessage_loopmessage_loop.cc:485)
base::MessageLoop::DoWork [0x119D974D+221] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbasemessage_loopmessage_loop.cc:594)
base::MessagePumpForIO::DoRunLoop [0x11A980A2+50] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbasemessage_loopmessage_pump_win.cc:524)
base::MessagePumpWin::RunWithDispatcher [0x11A99B42+130] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbasemessage_loopmessage_pump_win.cc:51)
base::MessagePumpWin::Run [0x11A99AAC+28] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbasemessage_loopmessage_pump_win.cc:58)
base::MessageLoop::RunHandler [0x119DA907+247] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbasemessage_loopmessage_loop.cc:438)
base::RunLoop::Run [0x11A0A2E6+70] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbaserun_loop.cc:56)
base::MessageLoop::Run [0x119DA7BD+237] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbasemessage_loopmessage_loop.cc:288)
base::Thread::Run [0x11A20AF6+22] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbasethreadingthread.cc:199)
content::BrowserThreadImpl::IOThreadRun [0x10603B74+52] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumcontentbrowserbrowser_thread_impl.cc:212)
content::BrowserThreadImpl::Run [0x1060498B+235] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumcontentbrowserbrowser_thread_impl.cc:246)
base::Thread::ThreadMain [0x11A215F9+745] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbasethreadingthread.cc:248)
base::`anonymous namespace'::ThreadFunc [0x11A283B6+262] (e:libqtqt_gitqt5qtwebenginesrc3rdpartychromiumbasethreadingplatform_thread_win.cc:84)
BaseThreadInitThunk [0x75D57C04+36]
RtlInitializeExceptionChain [0x77E4AD1F+143]
RtlInitializeExceptionChain [0x77E4ACEA+90]
(No symbol) [0x00000000]
崩溃的原因并不明显,因为Qt文档不清楚QWebEngineUrlSchemeHandler
应该如何实现的细节。
您的程序崩溃,因为QWebEngineUrlRequestJob::reply()
稍后在调用程序的作用域之外使用buffer参数,可能来自其他线程。到那时,您在堆栈上声明的局部变量QByteArray
arr(用作缓冲区的后备存储)将超出范围,QWebEngine将访问无效指针。
另一件事是,reply()
不拥有传递的buffer对象的所有权,也从不删除它。这会导致内存泄漏。由于与上述相同的原因,您不能在调用reply()
后立即删除它。为确保不再需要缓冲区对象时删除,请将请求的destroyed()
信号连接到缓冲器中的deleteLater()
插槽。
这是一个完整的工作和无泄漏的例子:
void CustomUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *request)
{
QBuffer *buffer = new QBuffer;
connect(request, SIGNAL(destroyed()), buffer, SLOT(deleteLater()));
buffer->open(QIODevice::WriteOnly);
buffer->write("<html><body>Hello world!</body></html>");
buffer->close();
request->reply("text/html", buffer);
}
注意:您根本不需要使用QByteArray
。QBuffer
的默认构造函数分配自己的存储。
崩溃的一个原因是arr超出了范围。
你必须更改
QByteArray arr = QString::fromStdString("<html><body>Hello world</body></html>").toUtf8();
QBuffer *buffer = new QBuffer(&arr, this);
至
QByteArray *pArr = new QByteArray(QString::fromStdString("<html><body>Hello world</body></html>").toUtf8());
QBuffer *buffer = new QBuffer(pArr, this);
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- C++:TypeDef使用元组
- 使用std::multimap迭代器创建std::list
- 从不同线程使用int64的不同字节安全吗
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 为什么在全局范围内使用"extern int a"似乎不行?
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用Google Mock来模拟gettimeofday()
- 如何使用默认参数等选择模板专业化
- 为什么使用 "this" 指针调用派生成员函数?
- 使用新行和不使用新行读取文件
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 如何确定我已使用非编码文件到达 EOF?
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 使用CMake创建QML插件
- 使用 LLVM 的 libc++ 时,__1 符号从何而来?
- 在std::cout之后使用std::cin时,换行符从何而来
- 为什么以及在何处在C++中使用引用和指针
- 基例如何影响使用递归函数的哪些行