Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Q_DECLARE_METATYPE with a DLL that may be loaded multiple times

Tags:

c++

qt

qt4

Using Qt 4.8 with C++. I'm working with application plugins that are loaded and unloaded at runtime. The same plugin may be loaded multiple times during the application's lifetime. One of these plugins uses Q_DECLARE_METATYPE on some types that need to be stored in a QVariant. When the plugin is reloaded later, the old declaration still points to the original memory space of the now-unloaded library. This results in access violations when Qt tries to create a QVariant from the re-declared meta type. We've already dealt with a similar issue with qRegisterMetaType(): we register meta types when the library is loaded and unregister those types just before the library is unloaded. Unfortunately, that doesn't seem to be an option when declaring rather than registering meta types.

How can we effectively handle cases where the library that declares a meta type is loaded and unloaded multiple times?

like image 993
Travis Christian Avatar asked Oct 07 '13 21:10

Travis Christian


2 Answers

To expand on Kuba Ober's answer, you need to unregister the meta type by calling QMetaType::unregisterType() (http://doc.qt.io/qt-4.8/qmetatype.html#unregisterType) with your type name prior to unloading your DLL. You should be able to unregister declared meta types in the same location that you unregister the types you've registered using qRegisterMetaType<T>. This should leave the Qt Meta Object system in a clean state (as least as far as your unloaded plug-in is concerned), so that the next time the plug-in is loaded, new meta type IDs will be generated. Specifically, when the DLL is loaded again, the Q_DECLARE_METATYPE macro will register your type again, this time with a new metatype_id, and QVariant should no longer give you access violations.

like image 188
iamtheddrman Avatar answered Oct 21 '22 13:10

iamtheddrman


When you look at what Q_DECLARE_METATYPE does, you see that it declares a template class specialization of QMetaTypeId<T> with a single qt_metatype_id() member that uses a static variable to store the value of qRegisterMetaType. If, as you claim, you're able to unregister the metatype, you're all set.

like image 45
Kuba hasn't forgotten Monica Avatar answered Oct 21 '22 14:10

Kuba hasn't forgotten Monica