PDA

View Full Version : QPluginLoader Qt 4



rianquinn
22nd January 2006, 22:51
I'm trying to load a custom plugin into an app I am making. This plugin isn't made for QtDesigner, it simply extends the functionality of an existing app. The problem is when I try to load the dll using QPluginLoader, isLoaded is always returing false. Not matter what I try. Here is my current attempts.

Here is my code
#include "main_frmPE.h"

main_frmPE::main_frmPE (QWidget * parent) :
QWidget (parent)
{
setupUi (this);
QPluginLoader menu (QApplication::applicationDirPath() + "/../lib/menu.dll");
if (menu.isLoaded ())
QMessageBox::information (this, "Info","Hello World");
else
QMessageBox::information (this, "Info","Yuk!!");

}

This is the plugin interface
// Define Qt definitions
#include <QtGui>

class Plugin_Interface
{
public:
virtual ~Plugin_Interface () {}
virtual void init () {}
virtual void run () {}
};

Q_DECLARE_INTERFACE (Plugin_Interface, "plugin.programmerseditor.menu/1.0");


and this is the plugin itself

// Define Qt definitions
#include <QtGui>

// Define plugin definitions
#include "../../main/plugins/plugin_interface.h"

class plugin_menu_interface:
public QObject, public Plugin_Interface
{
Q_OBJECT
Q_INTERFACES (Plugin_Interface)

public:
plugin_menu_interface ();
virtual ~plugin_menu_interface ();
void init () {}
void run () {}
};


// Define user definitions
#include "menu_interface.h"

plugin_menu_interface::plugin_menu_interface ()
{
qDebug ("Hello World");
}

plugin_menu_interface::~plugin_menu_interface ()
{

}



I guess the most useful thing would be some working example code on how to do this. Qt's documentation is terrible on this subject. Otherwise, if someone know what I am doing wrong, or has any hints please let me know. I have spent days on this and have had no luck. And I can't find any working code to use as an example. Thanks everyone

Rian

Codepoet
22nd January 2006, 23:34
...
main_frmPE::main_frmPE (QWidget * parent) :
QWidget (parent)
{
...
QPluginLoader menu (QApplication::applicationDirPath() + "/../lib/menu.dll");
...
}
...

Just use "../lib/menu.dll" - without appDirPath. Is the dll really there? Try to run the exe from command line, so that ../lib/menu.dll is that dll.
Do you use another build system as qmake?
Try to load your plugin with one of the plugandpaint sample. It will produce two different errors depending on what failed: Your plugin is not a "valid" plugin or it doesn't implement any of the interfaces. If it only does not implement any of the interfaces it should work with your application...

I had many headaches with the plugin system - finally decided to use my own. So good luck... :rolleyes:
It comes down to the fact that Qt 4 denies to load plugins which were not compiled with the same compiler, Qt 4 library version (debug / release) and maybe much more. The worst thing about that is, that you don't get any useful information about the problem.
If you have much time install the Qt 4 debug with the source code and debug the constructor call of QPluginLoader by stepping into that call. Then you can try to figure out where the problem is.

high_flyer
23rd January 2006, 09:34
I'm trying to load a custom plugin into an app I am making. This plugin isn't made for QtDesigner, it simply extends the functionality of an existing app.
I think it would be better for you to use QLibrary class indstead.

Mike
23rd January 2006, 13:28
Your CPP file of the plugin needs to define:

Q_EXPORT_PLUGIN2(PluginClassName, NameOfLibrary)

I don't see that in your sample code for the plugin.

Mike
23rd January 2006, 13:30
I don't know if you have looked at this sample. It worked for me:

http://doc.trolltech.com/4.1/tools-plugandpaintplugins-basictools.html

rianquinn
26th January 2006, 22:42
Thanks for your replies, The Q_EXPORT_PLUGIN2 didn't work.

Can't use QLibrary. This would require me to extern all my interfaces to "C" code which can't be done. Also, the QPluginLoader is new to Qt 4, which adds a much needed Interface Layer to plugins that should become the future of all Qt programming. This is something (in my opinion) that should be figured out instead of avoiding.

So far no luck. I am currently working with Troll Tech to figure out what is wrong. It has to be something simple. At this point, sample code is going to be the most useful thing. Has anyone actually gotten this to work. Is there an open source example, that I can diff with my code.

Thanks Guys for all of your help. I would like to be able to post a complete solution to this thread to help others in the future.

Rian

rianquinn
26th January 2006, 22:57
Ok,

Here is the solution!!! YEAH

Q_EXPORT_PLUGIN2 needs to be in the following format.

Q_EXPORT_PLUGIN2(TARGET, INTERFACE)

TARGET is the name of the library (meaning in your .pro file, you specify the output file name by using the variable TARGET). Mine should have been "menu".

INTERFACE is the name of the interface that you are using. Mine is plugin_interface

Finally, the constructor of the QPluginLoader, simply specifies the plugin file name and path. You still have to run the load function.

If anyone needs an example of this code, you can look at the open source "Programmers Editor" on source forge.

Rian

GreyGeek
27th January 2006, 20:22
...snip...
If anyone needs an example of this code, you can look at the open source "Programmers Editor" on source forge.
Rian

Got a URL?
I searched for "Programmers Editor" on source forge and the only project by that name was using Python. There are lots of "Programmers something Editor". Which one are you?:confused:

rianquinn
5th March 2006, 01:11
programmersedit.sourceforge.net, however code won't be available until this summer when I have more time (college student). However, the surrent code is working really good. Qt 4's model view architecture is amazing for such a concept.

Thanks

hypermole
2nd October 2006, 08:04
Q_EXPORT_PLUGIN2(TARGET, INTERFACE)

[...]

INTERFACE is the name of the interface that you are using. Mine is plugin_interface



shouldn't INTERFACE be 'plugin_menu_interface'? from the plug&paint example:


Q_EXPORT_PLUGIN2(pnp_basictools, BasicToolsPlugin)

where BasicToolsPlugin header is:


class BasicToolsPlugin : public QObject,
public BrushInterface,
public ShapeInterface,
public FilterInterface

Using 'plugin_interface' in Q_EXPORT_PLUGIN2 will make the compiler complain as the macro will try to create an instance of the plugin_interface class which cannot be instantiated as being pure virtual.

G.

PS anyway I cannot make it work nor cannot debug QPluginLoader..trolltech should do something about that, who can I complain with? :eek: