处理 QPluginLoader::load() 抛出的异常
Posted
技术标签:
【中文标题】处理 QPluginLoader::load() 抛出的异常【英文标题】:Handling exceptions thrown by QPluginLoader::load() 【发布时间】:2016-03-03 23:59:57 【问题描述】:我有 2 个 Qt 插件,主插件和辅助插件,main.dll
正在加载 helper.dll
。当main.dll
和helper.dll
都在同一个文件夹中时,我能够使用QPluginLoader
成功加载main.dll
。当helper.dll
不存在并且我尝试加载main.dll
时,会引发异常。这是可以理解的,因为找不到helper.dll
。我的任务是成功捕获抛出的异常,而不是让应用程序崩溃。此处调试时 Qt Creator 显示的内容:
下面的代码没有解决问题,所以我需要做点别的……
std::exception_ptr eptr;
QPluginLoader pluginLoader(packagePath);
try
pluginLoader.load();
catch(...)
eptr = std::current_exception();
【问题讨论】:
我想你在找不到 helper.dll 时在 main.dll 中抛出异常?你如何加载 helper.dll?通过以某种方式使用 Qt 框架还是...? @Radek,我没有抛出异常。在我调用 QPluginLoader 的 instance() 的那一刻,这就是引发异常的原因。我只是无法抓住它,因此我的应用程序崩溃了。我正在加载 main.dll,但 main.dll 内部使用了 helper.dll。 这是有道理的,因为 AFAIK Qt 不会抛出异常。对于这两种情况,load()
返回的布尔值都会很有趣。我认为问题将出在加载 helper.dll 的 main.dll 的一部分。对我来说,这看起来像是 OS API 的一个异常,因为你无法捕捉到它很奇怪。
@Radek,是的,是操作系统返回了那个异常,因为它发生在不同的进程中,我无法捕捉到它......
【参考方案1】:
我相信在这种情况下你应该使用 Windows __try / __except 扩展:
__try
// guarded code
__except ( expression )
// exception handler code
这种异常会让你捕获 SEH 错误,你可以在 MSDN 上找到一篇关于它的详细文章: https://msdn.microsoft.com/en-us/library/swezty51.aspx
另外,这是另一个话题,为了优雅地结束你也可以使用SetUnhandledExceptionFilter
。
【讨论】:
我确实读过 __try 和 __except。由于某种原因,我无法在 Qt creator 中编译该代码,即使我已经包含了来自 Microsoft 和 STL 的所有必需的头文件。你能用 Qt creator 试试,它编译并发布代码吗?谢谢!!【参考方案2】:我已经能够解决这个问题。问题是我的 Qt 应用程序没有自行部署(当 Qt 应用程序需要独立于 Qt 创建者运行时必须这样做。我将脚本添加到 Qt Creator 项目的.pro
文件中。一旦我这样做了,如果对QPluginLoader::load()
的调用返回false,我没有看到崩溃,而是通过调用QPluginLoader::errrorString()
生成的友好错误消息。
我的代码如下所示:
QPluginLoader pluginLoader(m_packagePath);
bool bLoaded = pluginLoader.load();
if (bLoaded)
QObject* plugin = pluginLoader.instance();
m_metaObject = plugin->metaObject();
if (m_metaObject == nullptr)
qCritical() << "Unable to obtain entry class of input plugin. Please check your plugin.";
return false;
else
qCritical() << "Message from Qt plugin loader:";
qCritical() << pluginLoader.errorString();
qCritical() << "Please make sure your input Qt plugin along with its dependencies are deployed with winqtdeploy.exe and in the same folder as your plugin.";
exit(-1);
我从另一个 *** 帖子中获取了部署脚本,可以在这里找到:
Automatic Copy of Dependent Files in Qt Creator
【讨论】:
这很有趣。这意味着您需要将另一个 dll 复制到路径中。几年前我写了一些插件时,我不记得我需要这样做。 @armanali 你没有问过pluginLoader.load(); 的条件吗?抛出?在这种情况下,您自己的代码不能成为解决方案。以上是关于处理 QPluginLoader::load() 抛出的异常的主要内容,如果未能解决你的问题,请参考以下文章
HttpApplication处理对象与HttpModule处理模块