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