将Q_DECLARE_METATYPE与可能多次加载的DLL一起使用

时间:2013-10-07 21:01:12

标签: c++ qt qt4

将Qt 4.8与C ++结合使用。我正在使用在运行时加载和卸载的应用程序插件。在应用程序的生命周期内,可以多次加载相同的插件。其中一个插件在某些需要存储在Q_DECLARE_METATYPE中的类型上使用QVariant。稍后重新加载插件时,旧声明仍指向现在卸载的库的原始内存空间。当Qt尝试从重新声明的元类型创建QVariant时,这会导致访问冲突。我们已经处理了与qRegisterMetaType()类似的问题:我们在加载库时注册元类型,并在卸载库之前注销这些类型。不幸的是,在声明而不是注册元类型时,这似乎不是一种选择。

我们如何有效地处理多次加载和卸载声明元类型的库的情况?

2 个答案:

答案 0 :(得分:1)

当您查看Q_DECLARE_METATYPE执行的操作时,您会看到它声明QMetaTypeId<T>的模板类特化,其中包含一个qt_metatype_id()成员,该成员使用静态变量来存储qRegisterMetaType的值。如果您声称自己能够取消注册元组类型,则可以全部设置。

答案 1 :(得分:1)

要扩展Kuba Ober的答案,您需要在卸载DLL之前使用您的类型名称调用QMetaType::unregisterType()http://doc.qt.io/qt-4.8/qmetatype.html#unregisterType)取消注册元类型。您应该可以在取消注册使用qRegisterMetaType<T>注册的类型的相同位置取消注册已声明的元类型。这应该使Qt元对象系统处于干净状态(至少与卸载的插件有关),以便下次加载插件时,将生成新的元类型ID。具体来说,当再次加载DLL时,Q_DECLARE_METATYPE宏将再次注册您的类型,这次使用新的metatype_id,而QVariant不应再为您提供访问权限。