Crash when closing application
-
@Joel-Bodenmann said:
The Plugin class is just a base class that allows me retrieving basic information about the plugin such as the plugin name, version and the author. This base class will also be useful in the future when there are plugins that aren't actually file viewers.
To summarize: Viewer inherits form Plugin, Editor inherits from Viewer.I wouldn't design it exactly like this, but I suggest leaving that question for after finding the problem.
But when actually writing this... I guess the name clone() is misleading in this case.
I must have been misled. I thought you're copying
QObject
s with this.As you can see, the Viewer is a plugin that allows opening and displaying a file.
I don't think it should be. But rather a class that's exposed from the plugin. That's what I was talking about in the first sentence. A plugin is a single(ton) object (of the .dll/.so) that represents the entry point. You can think of it as a factory of sorts. So usually the most convenient way to deal with that is like this:
class ViewerProvider { public: virtual QList<Viewer> viewers() = 0; } Q_DECLARE_INTERFACE(ViewerProvider) //< A plugin interface class EditorProvider { public: virtual QList<Editor> editors() = 0; }; Q_DECLARE_INTERFACE(EditorProvider) //< A plugin interface
Then the plugin will implement both if it provides both editors and viewers:
class MyCoolPlugin : public QObject, public ViewerProvider, public EditorProvider { Q_OBJECT Q_PLUGIN_METADATA(...) Q_INTERFACES(ViewerProvider EditorProvider) //< Listing all interfaces so moc will generate the TI we need for qobject_cast // .... };
Now, when loading we can inquire the plugin what it provides:
QPluginLoader pluginLoader(...); QObject * pluginObject = pluginLoader.instance(); //< This is the plugin - the entry point of the library, not the functionality we're after EditorProvider * editorprovider = qobject_cast<EditorProvider>(pluginObject); if (editorprovider) { // Superb our plugin provides editors, we can load those, or store the pointer to the plugin or whatever we need to do // The point is the plugin itself only aggregates the functionality } // ... And so on (analogically with ViewerProvider)
And by the way you don't need the destructors in your interfaces. They will generate object code (because virtual methods can't be inlined) and you don't really need to enforce them virtual, as
QObject
already does that.I will try to create a minimum test-case that allows you reproducing the problem. However, that might take a couple of days (most likely I'll get it done over the weekend).
If there's nothing secretive about the code (i.e. it's not protected by copyright or something like this) you could upload it in a repo somewhere as it is. I'd download it in the evening and check if I can find the problem.
Kind regards.
@kshegunov said:
And by the way you don't need the destructors in your interfaces. They will generate object code (because virtual methods can't be inlined) and you don't really need to enforce them virtual, as QObject already does that.
The reason I added those virtual destructors there is because Qt documenation adviced me to do so: https://doc.qt.io/qt-4.8/qt-tools-plugandpaint-example.html
The class also has a virtual destructor. Interface classes usually don't need such a destructor (because it would make little sense to delete the object that implements the interface through a pointer to the interface), but some compilers emit a warning for classes that declare virtual functions but no virtual destructor. We provide the destructor to keep these compilers happy.
-
@kshegunov said:
And by the way you don't need the destructors in your interfaces. They will generate object code (because virtual methods can't be inlined) and you don't really need to enforce them virtual, as QObject already does that.
The reason I added those virtual destructors there is because Qt documenation adviced me to do so: https://doc.qt.io/qt-4.8/qt-tools-plugandpaint-example.html
The class also has a virtual destructor. Interface classes usually don't need such a destructor (because it would make little sense to delete the object that implements the interface through a pointer to the interface), but some compilers emit a warning for classes that declare virtual functions but no virtual destructor. We provide the destructor to keep these compilers happy.
The reason I added those virtual destructors there is because Qt documenation adviced me to do so
Right, it's not an error by any means. However, I advise not using substandard compilers instead. ;)