Search code examples
c++qtqt4

Using Q_DECLARE_METATYPE with a DLL that may be loaded multiple times


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?


Solution

  • 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.