处理 QPluginLoader::load() 抛出的异常

Posted

技术标签:

【中文标题】处理 QPluginLoader::load() 抛出的异常【英文标题】:Handling exceptions thrown by QPluginLoader::load() 【发布时间】:2016-03-03 23:59:57 【问题描述】:

我有 2 个 Qt 插件,主插件和辅助插件,main.dll 正在加载 helper.dll。当main.dllhelper.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处理模块

自然语言处理_一般处理流程

怎么在批处理中加回车命令?

throws关键字_异常处理的第一种方式(交给别人处理)和try_catch_异常处理的第二种方式(自己处理)

PHP异常处理

协处理器,王明学learn