PDA

View Full Version : Communication between QT Plug-In's



andreoq
6th February 2011, 00:59
Hello,

I have created a Plug-In's System. I have a ItemFactory and a lot of Item's based on this ItemFactory.

The Problem is; I can not create instance or call functions of a plugin inside of an other plugin. Also

A = ItemA : public ItemFactory
B = ItemB : public ItemFactory

I can communicate with A and B from main Window. But A dont have any access on B.

Is there a solution?

edit: I experienced that i can access public variables but can not still access public functions and only create pointers but not a instance of the class

d_stranz
6th February 2011, 01:48
If a plug-in has a function (say printing) that other plug-ins might want to use, then the plug-in should have some way of telling the plug-in manager (the application) what kinds of functions it provides. So, when a plug-in is loaded, it tells the manager "Hey, I'm a print plug-in!" and the manager adds it to the list of plug-ins that support printing. Another plug-in might ask the manager, "Hey, I need a printer!" and the manager says, "Sure, here's the list. Ask them if any one supports the kinds of printing you need".

What this implies from an architecture point of view is that simply having an ItemFactory that creates Items without any more information than that is not a workable solution. If each type of Item has a different set of capabilities, then it needs to be able to communicate to a manager or to another Item what it can do.

The usual plug-in way of doing this is to divide different functions into "SomethingInterface" classes derived from some "Interface" base class, virtual classes that define a particular set of capabilities. So maybe you have a PrintInterface, and a FileIOInterface, or a VideoInterface. In order for the manager to be able to use these, it has to know what each of these ...Interface classes can do, so it needs to #include the .h file that defines the ...Interface and its methods. Likewise, if one plug-in wants to use another, it also needs to be built with knowledge of what the ...Interface methods are.

So, the manager knows about all the interfaces it is interested in, like PrintInterface, FileIOInterface, VideoInterface. When it loads a new plug-in, then it asks the plug-in, "Do you support the PrintInterface? OK, I'll add you to the Printers list. Do you support the FileIOInterface? No? What about the VideoInterface?" and so on.

Another plug-in can ask the manager, "Give me the list of all your plug-ins" and do the same question and answer on each of them until it finds one it can use, or if the manager is better organized than that, it can directly answer a question like "Give me all the printers".

This implies that the manager also needs to have its own ManagerInterface methods that all plug-ins know about, because otherwise there would be no way for them to communicate with whoever loaded them.

Does that get to what you were asking?

andreoq
6th February 2011, 02:26
hi, thanks for reply,

I actually knew about this kind of plug in systematic you wrote about, but i wanted to deploy a system which the plug ins can have independent functions of Interface Class.

Also in your description the Manager give a object to a PlugIn, this PlugIn modifies the object and give it back to Manager. The manager give the same object continued to an other PlugIn.

I would like to get the Object from Manager, modify it and give to another PlugIn.

Why i wonder; that i can use public member variables but not the functions of the PlugIn Class. I also can get Pointer on him, but as soon as i call a function, gcc doesnt compile anymore.

Any way, i worked it around by using Signal-Slot Systematic, 'cause i have the pointer on my target PlugIn, i can invoke (emit) a slot of it. The Problem lies probably that my current PlugIn cant load dll (LoadLibrary) of the target PlugIn's.

It would be nice that such a theme (intercommunication of plugin's) were included to the Qt Plug-In Documentation.

d_stranz
6th February 2011, 17:59
I don't know your code, but if you are trying to use one class to call (emit) signals of another, that will not compile because the "signals:" keyword is identical to "protected:". So unless Class A is derived from Class B, then A cannot emit B's signals.

And don't you know? Public variables are evil in good C++. You should never, ever, make a variable public where some other code could simply change it to anything else. This is especially true for a plug-in system. What if some dumb user wrote a plug-in that changed one of those public variables to something completely incorrect? Suddenly your whole software crashes because of that dumb user's bad programming. And since the bad user is modifying that variable directly, there's absolutely no way for you to detect it. No signal, no slot, no nothing. The variable just mysteriously changes value, and the next time some other plug-in uses it, "Boom!".

wysota
6th February 2011, 21:06
I would like to get the Object from Manager, modify it and give to another PlugIn.
Have a look at the "chain of responsibility" design pattern. I don't know if it fits your exact use-case but maybe it's something you could use or adapt to your needs (or adapt your code to the pattern).

s200999900
16th February 2011, 11:54
d_stranz:
I am a nub in programming :)
Your information is very useful for me:)
Can you give a simple example of your description of the connection between plug-ins? If it can be an example of plugin manager.
and another question:) As for the class ItemFactory, where i can find description of it, in the official documentation describe him not :( ?

DarwinSurvivor
16th February 2011, 12:50
I believe I am running into a similar problem (if not, please let me know and I'll start a new thread).
I am using a factory system to generate a class. This class needs to handle classes defined in the application itself, but whenever I try to use the function of an application-defined class, I get a runtime "undefined symbol" error saying it can't find it. The same function in the same class works when accessed directly by the application itself, it only errors out when a *plugin* tries to use it.

If the class in the application is Foo, the following works:
Foo foo;
but not:
Foo foo();
or:
Foo foo;
foo.bar();

I have successfully recreated the problem in a scratch-written demo app that does nothing more than try a plugin.
I think it may be related to your problem of not being able to access public function or instances of classes.

To help, here (http://darwinsurvivor.homelinux.org/files/plugin_test.zip) is a zip file containing the simple demonstration of failure.