For a large software system, the implementation of plugin is a wonderful thing, a successful plugin system can add a lot of software. The biggest function of plugin is to improve the software flexibility and expansibility to some extent. A well-designed Server Software plugin system can even invoke the newly joined plugin without the server program exiting, enabling an uninterrupted service upgrade. So, how does QT implement its plugin system?
Using QT to create plugin and call plugin in the program is simple, and QT offers a lot of helper classes for everyone to use. Overall, QT plugin is divided into 2 kinds, according to the QT document, one is a high-level plugin. In fact, plainly is already determined interface Qt itself plugin. (As you may all know, QT's many functions, such as database driver, image format support, text inside code, etc. are implemented through plugin) For example, QT may not itself have Spanish (hope this Spanish title:-), but the programmer can be in accordance with codec Interface writes the Spanish codec plugin so that QT supports the Spanish language.
The other is a low-grade plugin. The interface of the plugin also needs to be written by the programmer himself. So if you know how to write a low-grade plugin and use it, the high-level plugin is fully mastered. Let me highlight some of the key points that low-level plugin have achieved in QT.
From a programmatic point of view, the focus is on OOP. The so-called plugin, in fact, are some sub-categories written in accordance with the specific interface. The interface must be a virtual base class, and all functions (except destructors) are virtual functions. The so-called plugin is the subclass that inherits the virtual base class and Qobject. When a program calls a function of the plugin, it is performed by the vtable of the plugin, which is dynamically bound to the subclass at run time. So the basis of QT realization Plugin is the inheritance and polymorphism of OOP.
As everyone knows, there is a unified interface virtual base class for all filters in PhotoShop (which may not be possible), and this class provides a virtual function Dosomework for implementing the filter effect. When the user selects a particular filter, the program invokes the Dosomework implementation function of the filter class in plugin to perform the operation, which implements the specific filter functionality.
So why should the plugin class not only inherit the interface class, but also inherit the Qobject class? The reason is that the meta information for the plugin class Qobject is required when calling plugin. If you look at the example code, you will find that the key step after calling plugin's file with Qpluginloader is to determine what type of plugin it is. The simple surprise of the others, a qobject_cast. Just see this sentence I think the solution, in the QT has the source code to see, see the source code found qobject_cast similar to the standard C + + dynamic_cast, and without rtti support and can cross the DLL. In the code, Qobject_cast is implemented by the cast function of the Qobject metaobject. So what does the function say?
/*!
/internal
returns/a obj if object/a obj inherits from this
Meta-object; otherwise returns 0.
*/
Qobject *qmetaobject::cast (qobject *obj) const
{
if (obj) {
Const Qmetaobject *m = Obj->metaobject ();
do {
if (m = = this)
return const_cast<qobject*> (obj);
} while ((M = m->d.superdata));
}
return 0;
}
Starting with the metaobject of the subclass, the parent class loops until a consistent meta (class information) is found. So, Qobject_cast actually determines whether the class is a derived class that specifies the parent class, and if so, gets its pointer. That is to say, determine what type of plugin is implemented through inheritance relationships.
From the file point of view, one or more plugin can live in the same dynamic library, under Windows is a DLL. So, how can this DLL dynamically expose plugin to the caller? The key is to Q_EXPORT_PLUGIN2 this macro. The QT documentation specifically explains that the same plugin must and can only be called once, and must be at the end of the implementation file. Why is it?
Because this macro eventually calls another macro, q_plugin_instance, and it's defined as follows:
#define Q_PLUGIN_INSTANCE (Implementation)/
{ /
Static Qt_prepend_namespace (Qpointer) <qt_prepend_namespace (qobject) > _instance; /
if (!_instance)/
_instance = new Implementation; /
return _instance; /
}
I don't know if you've noticed the static and let a cute pattern in design patterns sweep through your mind. From this perspective, the code that is best for you to complete in plugin is the transactional code that uses the caller's resources to perform certain calculations or operations. Think twice when you want to allocate a lot of resources and organize a large class team in plugin.
Other details such as how to configure the Pro file, plugin file directory and so on are some of the details, you can see the document to solve.
I don't know if I'm writing too little and jumping too much. I think everyone is very high, some simple details are not time-consuming and laborious description. Just write the information that you think is interesting and important. TX is interested in words can also write something to communicate with each other, after all, QT's Chinese information is too small.
Finally, I have some ideas about the recent hot Emperor Don's story. But I this Bo is mainly technical articles, so I only say a word and we encourage each other. "Honesty is more valuable than gold."
http://blog.csdn.net/superjoel/article/details/5725209
Several explanations of Qt plugin system