PDA

View Full Version : Plugins and Inheritance



darkadept
7th December 2007, 23:27
Ok I've been slamming my head against my desk all day now but I think I have some solution. I'm looking for some clarification or agreement or explanation or something. :)

I have a shared library that I'm linking to from my application that contains a simple QObject class:


class MyBaseClass : public
{
Q_OBJECT
public:
MyBaseClass(QObject *parent=0) { }
virtual ~MyBaseClass() { } //side-note: is this 'virtual' needed and/or problematic?
virtual void doSomething() {
qDebug() << "i'm doing something from my base class";
}
}


I also have a dynamic library that I'm loading using QPluginLoader. In this plugin I am wanting to inherit MyBaseClass like this:


class MyInheritedClass : public MyBaseClass {
Q_OBJECT
public:
MyInheritedClass(QObject *parent=0) { }
~MyInheritedClass() { }
void doSomething() {
qDebug() << "i'm doing something from my inherited class";
}
}


I'm starting to realize that this probably the wrong approach. Please enlighten me. I'm realizing that you probably can't have this kind of inheritance across the plugin boundary. I guess the right way to do it is to have an interface declared in the shared library and have a default concrete class in the shared library and my specific plugin class in my plugin.


//These two inside my shared library
class MyInterface { ...
class MyDefaultClass : public QObject, public MyInterface { ...

//And this one inside my plugin
class MySpecificClass : public QObject, public MyInterface { ...


Of course this doesn't work exactly the same as inheriting from a base class, but i think i can make it work.

Now.... here's the REAL kicker to all this. My first example works perfectly under Linux. It does NOT work under Windows with MinGW.
That's what got me so confused. I had perfectly working code when I developed under Linux. Then I moved my source over to windows and it compiles fine. When I try to load my plugin QPluginLoader::instance() returns a null pointer.

So anyway, if any one can shed some light on this I would be grateful.

-Mike

wysota
8th December 2007, 00:09
Under Windows you have to use __decl(dllexport) and __decl(dllimport) to export/import appropriate symbols. There is a macro in Qt that handles it transparently. Search the docs for dllexport, I'm sure you'll find it. I don't know if this is the problem you are facing but it's a likely candidate.

darkadept
10th December 2007, 21:13
Yup you're right, although there is very little documentation in the Qt docs.

Here is what I did after gleaning information from all over the web. (BTW, this only affects Windows compiles).

If you have a library and you want your class (or functions) to be used by other apps linking to it you have to export them.

I made a new header file (i called my libdef.h) with this:


#ifndef LIBDEF_H
#define LIBDEF_H

#include <Qt/qglobal.h>

#if defined(Q_OS_WIN32)
# ifdef MYLIB
# define MYEXPORT Q_DECL_EXPORT
# else
# define MYEXPORT Q_DECL_IMPORT
# endif
#else
# define MYEXPORT
#endif

#endif


Then the class in my shared library needs to look like this:


#include "libdef.h"

class MYEXPORT MyClassName
{
public:
//methods & etc here
};

class MYEXPORT AnotherClassName
{
//etc...
};


In my .pro file for my shared library I added this line:


DEFINES += MYLIB


Remember, this is needed for Windows systems only. But the above code works on all platforms.

My main beef is that they do not use this necessary method in any of the Qt docs or in any of the Qt examples. Hopefull my post helps others.