6

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

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

4

2 回答 2

1

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

于 2013-10-08T19:08:46.187 回答
1

当您查看 Q_DECLARE_METATYPE 所做的事情时,您会看到它声明了一个模板类特化,QMetaTypeId<T>其中包含一个qt_metatype_id()成员,该成员使用静态变量来存储 的值qRegisterMetaType。如果,正如您所声称的,您能够取消注册元类型,那么您就完成了。

于 2013-10-07T22:10:55.447 回答