Hello all...
I've been staring at this for over an hour and I've got to admit... I'm about out of ideas.
I have a plugin (using the low-level approach) that QPluginLoader returns a NULL pointer on when instance() is called. This tends to tell me that (a) The plugin is not being built as a plugin, (b) Qt is not recognizing some name somewhere, or (c) I'm just losing my mind.
I have several other *kinds* of plugins, all of which work perfectly. This is the only plugin of its kind, so it's possible that the plugin interface is borked.
Anyways, each plugin inherits from a master plugin interface (combines common functionality into a single class which all other plugins inherit from):
class evilcpcPlugin
{
public:
virtual ~evilcpcPlugin(){}
/** Returns a short, descriptive name for this plugin*/
virtual const QString getName
()const = 0;
/** Returns a longer description for this plugin*/
virtual const QString getDescription
()const = 0;
/** Returns the name of the author of this plugin*/
virtual const QString getAuthor
()const = 0;
/** Checks whether or not this plugin has encountered an error*/
virtual const bool isValid()const = 0;
/** Returns the nature of an error if this plugin is marked as invalid*/
virtual const QString errorString
()const = 0;
/** This will return an instance of the configuration dialog for this
* plugin. Return a 0 if you need no configuration*/
virtual evilcpcPluginWidgetConfig
* getConfigWidget
(QWidget * parent
) = 0;
/** This will return an instance of the carPC-side daemon utilized for
* remote configuration of this plugin. Return a 0 if your plugin needs
* no configuration*/
virtual evilcpcPluginWidgetConfigDaemon
* getConfigWidgetDaemon
(QWidget * parent
) = 0;
};
class evilcpcPlugin
{
public:
virtual ~evilcpcPlugin(){}
/** Returns a short, descriptive name for this plugin*/
virtual const QString getName()const = 0;
/** Returns a longer description for this plugin*/
virtual const QString getDescription()const = 0;
/** Returns the name of the author of this plugin*/
virtual const QString getAuthor()const = 0;
/** Checks whether or not this plugin has encountered an error*/
virtual const bool isValid()const = 0;
/** Returns the nature of an error if this plugin is marked as invalid*/
virtual const QString errorString()const = 0;
/** This will return an instance of the configuration dialog for this
* plugin. Return a 0 if you need no configuration*/
virtual evilcpcPluginWidgetConfig * getConfigWidget(QWidget * parent) = 0;
/** This will return an instance of the carPC-side daemon utilized for
* remote configuration of this plugin. Return a 0 if your plugin needs
* no configuration*/
virtual evilcpcPluginWidgetConfigDaemon * getConfigWidgetDaemon(QWidget * parent) = 0;
};
To copy to clipboard, switch view to plain text mode
This base class works fine with other plugin types. The actual interface class is this:
# include <QtPlugin>
# include <evilcpcPlugin.h>
class evilcpcMixerWidget;
/** This interface fills the purpose of describing and creating a given mixer
* plugin */
class evilcpcMixer : public evilcpcPlugin
{
public:
virtual ~evilcpcMixer(){}
/** Creates an widget for the mixer plugin to use. This widget will
* handle control of all audio mixer properties. This will stay
* resident at all times.
* @parent - This will be a pointer to the menu plugin's widget*/
virtual evilcpcMixerWidget
* getWidget
(QWidget * parent
) = 0;
};
Q_DECLARE_INTERFACE(evilcpcMixer,
"com.warfaresdl.evilcpc.evilcpcMixer/1.0.0")
# include <QtPlugin>
# include <evilcpcPlugin.h>
class QWidget;
class evilcpcMixerWidget;
/** This interface fills the purpose of describing and creating a given mixer
* plugin */
class evilcpcMixer : public evilcpcPlugin
{
public:
virtual ~evilcpcMixer(){}
/** Creates an widget for the mixer plugin to use. This widget will
* handle control of all audio mixer properties. This will stay
* resident at all times.
* @parent - This will be a pointer to the menu plugin's widget*/
virtual evilcpcMixerWidget * getWidget(QWidget * parent) = 0;
};
Q_DECLARE_INTERFACE(evilcpcMixer,
"com.warfaresdl.evilcpc.evilcpcMixer/1.0.0")
To copy to clipboard, switch view to plain text mode
Pretty simple stuff... I can't imagine there's anything screwy here. Then there's the plugin class, which fills in all the pure virtuals:
# include <evilcpcMixer.h>
# include <QObject>
class evilcpcMixerOSS
: public QObject,
public evilcpcMixer
{
Q_OBJECT
Q_INTERFACES(evilcpcMixer)
public:
evilcpcMixerOSS
(QObject * parent
= 0);
virtual ~evilcpcMixerOSS();
virtual const QString getName
()const{return tr
("OSSv3 mixer");
} virtual const QString getDescription
()const{return tr
("Mixer plugin utilizing the OSS v3 library");
} virtual const QString getAuthor
()const{return "Richard F. Ostrow Jr.";
} virtual const bool isValid()const{return valid;}
virtual const QString errorString
()const{return error;
} virtual evilcpcMixerWidget
* getWidget
(QWidget * parent
);
virtual evilcpcPluginWidgetConfig
* getConfigWidget
(QWidget * parent
);
virtual evilcpcPluginWidgetConfigDaemon
* getConfigWidgetDaemon
(QWidget * parent
);
protected:
bool valid;
evilcpcMixerWidget * w;
evilcpcPluginWidgetConfig * cw;
evilcpcPluginWidgetConfigDaemon * cwd;
};
# include <evilcpcMixer.h>
# include <QObject>
class evilcpcMixerOSS : public QObject, public evilcpcMixer
{
Q_OBJECT
Q_INTERFACES(evilcpcMixer)
public:
evilcpcMixerOSS(QObject * parent = 0);
virtual ~evilcpcMixerOSS();
virtual const QString getName()const{return tr("OSSv3 mixer");}
virtual const QString getDescription()const{return tr("Mixer plugin utilizing the OSS v3 library");}
virtual const QString getAuthor()const{return "Richard F. Ostrow Jr.";}
virtual const bool isValid()const{return valid;}
virtual const QString errorString()const{return error;}
virtual evilcpcMixerWidget * getWidget(QWidget * parent);
virtual evilcpcPluginWidgetConfig * getConfigWidget(QWidget * parent);
virtual evilcpcPluginWidgetConfigDaemon * getConfigWidgetDaemon(QWidget * parent);
protected:
QString error;
bool valid;
evilcpcMixerWidget * w;
evilcpcPluginWidgetConfig * cw;
evilcpcPluginWidgetConfigDaemon * cwd;
};
To copy to clipboard, switch view to plain text mode
Again, pretty simple. And the implementation also contains the Q_EXPORT_PLUGIN2 line, as follows:
Q_EXPORT_PLUGIN2(LIBTARGET, evilcpcMixerOSS)
Q_EXPORT_PLUGIN2(LIBTARGET, evilcpcMixerOSS)
To copy to clipboard, switch view to plain text mode
LIBTARGET is defined in the end of the project file:
TEMPLATE = lib
HEADERS += evilcpcMixerOSS.h \
evilcpcMixerOSSWidget.h \
evilcpcMixerOSSWidgetConfig.h \
evilcpcMixerOSSWidgetConfigDaemon.h \
../interface/evilcpcMixer.h \
../interface/evilcpcMixerWidget.h \
../../interface/evilcpcPluginWidgetConfig.h \
../../interface/evilcpcPluginWidgetConfigDaemon.h \
../../interface/evilcpcPlugin.h
SOURCES += evilcpcMixerOSS.cpp \
evilcpcMixerOSSWidget.cpp \
evilcpcMixerOSSWidgetConfig.cpp \
evilcpcMixerOSSWidgetConfigDaemon.cpp
FORMS += formOSSMixer.ui \
formOSSMixerConfig.ui
RESOURCES += ossmixer.qrc
VERSION = 1.0.0
CONFIG += plugin debug_and_release qt resources
QT += core gui
INCLUDEPATH = ../interface ../../interface
CONFIG(debug, debug|release) {
TARGET = evilcpcMixerOSS_debug
DEFINES += LIBTARGET=evilcpcMixerOSS_debug
} else {
TARGET = evilcpcMixerOSS
DEFINES += LIBTARGET=evilcpcMixerOSS
}
TEMPLATE = lib
HEADERS += evilcpcMixerOSS.h \
evilcpcMixerOSSWidget.h \
evilcpcMixerOSSWidgetConfig.h \
evilcpcMixerOSSWidgetConfigDaemon.h \
../interface/evilcpcMixer.h \
../interface/evilcpcMixerWidget.h \
../../interface/evilcpcPluginWidgetConfig.h \
../../interface/evilcpcPluginWidgetConfigDaemon.h \
../../interface/evilcpcPlugin.h
SOURCES += evilcpcMixerOSS.cpp \
evilcpcMixerOSSWidget.cpp \
evilcpcMixerOSSWidgetConfig.cpp \
evilcpcMixerOSSWidgetConfigDaemon.cpp
FORMS += formOSSMixer.ui \
formOSSMixerConfig.ui
RESOURCES += ossmixer.qrc
VERSION = 1.0.0
CONFIG += plugin debug_and_release qt resources
QT += core gui
INCLUDEPATH = ../interface ../../interface
CONFIG(debug, debug|release) {
TARGET = evilcpcMixerOSS_debug
DEFINES += LIBTARGET=evilcpcMixerOSS_debug
} else {
TARGET = evilcpcMixerOSS
DEFINES += LIBTARGET=evilcpcMixerOSS
}
To copy to clipboard, switch view to plain text mode
I went to the trouble of making sure that each interface was included in the HEADERS line of the project file, used the lib template, and added plugin to the CONFIG line. What could I possibly be missing?
Bookmarks