gpt4 book ai didi

c++ - 为什么不为动态加载的 Qt 插件类调用析构函数?

转载 作者:行者123 更新时间:2023-11-30 04:14:15 25 4
gpt4 key购买 nike

在我的 C++ Qt 应用程序(一个字典查找/测验程序)中,我使用插件来为人们可能想要添加和使用的所有可能的语言提供功能。这些插件在运行时从主小部件的构造函数中搜索和加载:

void MainForm::loadPlugins()
{
QDir curDir;
QStringList pluginFilter;
pluginFilter << "*_plugin.dll";
QStringList pluginFiles = curDir.entryList(pluginFilter, QDir::Files);

for (int i = 0; i < pluginFiles.size(); ++i)
{
const QString &pluginFile = pluginFiles.at(i);
QPluginLoader loader(pluginFile);
DictionaryPlugin *plug = qobject_cast<DictionaryPlugin*>(loader.instance());
if (plug)
{
plugins_.append(plug);
}
}
}

我曾经认为我应该自己销毁加载的插件,所以我在 ~MainForm(),依次删除它们。后来我从 QPluginLoader 的文档中发现我不应该那样做。此外,它还导致了一个奇怪的错误,该错误导致程序在关闭时卡住(但仅在调试器下运行后),因此显然存在问题。

我从 ~MainForm() 中删除了删除部分,一切似乎都工作正常,只是我注意到插件的析构函数没有被调用。我依靠那些在应用程序终止时保存一些特定于插件的设置,否则我不会注意到。我在其中一个析构函数上放置了一个断点,但调试器从未进入它。

这是插件的概要:

// dict_plugin.h
class DictionaryPlugin
{
public:
virtual ~DictionaryPlugin() {}

virtual QString name() const = 0;
virtual QString language() const = 0;
/* ... */
};

Q_DECLARE_INTERFACE(DictionaryPlugin, "DictionaryPlugin")

// jp_plugin.h
class JpPlugin : public QObject, public DictionaryPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "JpPlugin")
Q_INTERFACES(DictionaryPlugin)

public:
JpPlugin();
virtual ~JpPlugin();

virtual QString name() const { return QString("Japanese plugin v1.0"); }
virtual QString language() const { return QString("Japanese"); }
/* ... */
};

// jp_plugin.cpp
JpPlugin::~JpPlugin()
{
saveSettings();

delete dictWidget_;
delete settWidget_;

delete kanjiDialog_;
delete wordDialog_;
delete radicalDialog_;
}

我的问题是,插件是如何销毁的?显然它们必须是,当我的程序终止后操作系统回收内存时。为什么析构函数被省略了?还有其他方法可以让我释放它们吗?也许在 MainForm 类中保留原始的 QPluginLoader 对象,然后在析构函数中手动 unload() 它们?析构函数还负责销毁插件拥有的一些 QDialog 和 UI 小部件。这是否意味着我在程序退出时发生泄漏?

谢谢!

更新:我尝试为每个插件存储指向 QPluginLoader 的指针。在 ~MainForm() 中,我遍历它们,调用 unload()delete。工作正常,除了卡住错误又回来了。当我关闭应用程序时,窗口消失了,但程序仍在调试器中运行。我可以暂停它,但堆栈只显示 ntdll.dll 中的一些未识别的入口点。似乎没有立即发生任何坏事,正常运行时甚至看不到它,但不知何故让我感到不安。

更新 2: 我让程序在卡住状态下运行(忘记停止它),一段时间后发现它正常终止;只花了大约 20 多秒。现在我非常惊讶。什么可能导致这种情况?

最佳答案

我在 Google 上找到了这个:

QPluginLoader has its own ref counting and will delete the plugin when unload() has been called for it for each QPluginLoader instance that has a handle on it. unload() is not called automatically in the QPluginLoader destructor so a plugin is never automatically deleted.

它可以追溯到 2010 年,但也许您应该尝试保留对加载程序的引用,并在程序结束时手动对它们调用卸载。

文章链接如下:

How to unload modules in Qt

关于c++ - 为什么不为动态加载的 Qt 插件类调用析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18994192/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com