Hello all,

I've been following the docs for developing a plugin for my Qt application, using the low-level approach, as well as the plug & paint example. For whatever reason, when I run my application, it detects the plugin files but cannot generate an instance from them. Here's what I've got (using a single plugin as an example, and the relevant sections of my application).

First, I'll start with my interface, input.h:
Qt Code:
  1. #ifndef INPUT_H
  2. #define INPUT_H
  3.  
  4. # include <QObject>
  5.  
  6. class QPoint;
  7.  
  8. class input
  9. {
  10. Q_OBJECT
  11. public:
  12. input() : allow(true){}
  13. virtual ~input(){}
  14.  
  15. virtual const QString getName()const = 0;
  16. virtual const QString getDescription()const = 0;
  17. public slots:
  18. virtual void setAllow(bool allow) = 0;
  19. signals:
  20. void menuUp();
  21. void menuDown();
  22. void menuLeft();
  23. void menuRight();
  24. void tap(const QPoint & p);
  25. protected:
  26. bool allow;
  27. };
  28.  
  29. Q_DECLARE_INTERFACE(input,
  30. "com.warfaresdl.evilcpc.input/1.0.0")
  31.  
  32. #endif
To copy to clipboard, switch view to plain text mode 
And below, a sample input plugin, inputvoice.h:
Qt Code:
  1. #ifndef INPUTVOICE_H
  2. #define INPUTVOICE_H
  3.  
  4. # include <input.h>
  5.  
  6. class inputVoice : public input, public QObject
  7. {
  8. Q_OBJECT
  9. Q_INTERFACES(input)
  10. public:
  11. inputVoice(QObject * p = 0);
  12. virtual ~inputVoice();
  13.  
  14. virtual const QString getName()const;
  15. virtual const QString getDescription()const;
  16. public slots:
  17. virtual void setAllow(const bool allow);
  18. };
  19.  
  20. #endif
To copy to clipboard, switch view to plain text mode 
... and its implementation, inputVoice.cpp:
Qt Code:
  1. #include "inputVoice.h"
  2. #include <QtPlugin>
  3.  
  4. inputVoice::inputVoice(QObject * p) : input(), QObject(p)
  5. {
  6. }
  7.  
  8. inputVoice::~inputVoice()
  9. {
  10. }
  11.  
  12. const QString inputVoice::getName()const
  13. {
  14. return tr("Voice");
  15. }
  16.  
  17. const QString inputVoice::getDescription()const
  18. {
  19. return tr("Voice input plugin");
  20. }
  21.  
  22. void inputVoice::setAllow(const bool a)
  23. {
  24. allow = a;
  25. }
  26.  
  27. Q_EXPORT_PLUGIN2(inputVoice, inputVoice)
To copy to clipboard, switch view to plain text mode 
The qmake .pro file for this plugin (voice):
Qt Code:
  1. TEMPLATE = lib
  2. HEADERS = inputVoice.h
  3. SOURCES = inputVoice.cpp
  4. VERSION = 1.0.0
  5. CONFIG = plugin debug_and_release qt
  6. QT = core
  7. INCLUDEPATH = ../interface
  8.  
  9. CONFIG(debug, debug|release) {
  10. TARGET = inputVoice_debug
  11. } else {
  12. TARGET = inputVoice
  13. }
To copy to clipboard, switch view to plain text mode 
This generates a file, libinputVoice.so, which I sym-link to my application's project directory under a "plugins" sub-folder. My application uses the following qmake project file:
Qt Code:
  1. CONFIG = debug_and_release qt warn_on thread
  2. QT = core
  3. TEMPLATE = app
  4. HEADERS =
  5. SOURCES = main.cpp
  6. INCLUDEPATH = ../plugins/menu/interface \
  7. ../plugins/menuItem/interface \
  8. ../plugins/input/interface
  9. LIBS += -lmenu \
  10. -lpanel \
  11. -lncurses
  12.  
  13. CONFIG(debug, debug|release) {
  14. TARGET = evilcpcconf-debug
  15. } else {
  16. TARGET = evilcpcconf
  17. }
To copy to clipboard, switch view to plain text mode 
... and in my application code, I use the following to load the plugin (stderr has been redirected to error.log via freopen):
Qt Code:
  1. unsigned int index;
  2. //load plugins at this point...
  3. QStringList lPluginName;
  4. QStringList lPluginDescription;
  5. QStringList lPluginFile;
  6. QDir pluginsDir = QDir(QCoreApplication::applicationDirPath());
  7. #if defined(Q_OS_WIN)
  8. if(pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
  9. {
  10. pluginsDir.cdUp();
  11. }
  12. #elif defined(Q_OS_MAC)
  13. if(pluginsDir.dirName() == "MacOS")
  14. {
  15. pluginsDir.cdUp();
  16. pluginsDir.cdUp();
  17. pluginsDir.cdUp();
  18. }
  19. #endif
  20. cerr << "Using plugin path: " << pluginsDir.absolutePath().toAscii().data() << endl;
  21. pluginsDir.cd("plugins");
  22. cerr << "Changed to: " << pluginsDir.absolutePath().toAscii().data() << endl;
  23. foreach(QString fileName, pluginsDir.entryList(QDir::Files))
  24. {
  25. cerr << "Found a file: " << pluginsDir.absoluteFilePath(fileName).toAscii().data() << endl;
  26. QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
  27. QObject * plugin = loader.instance();
  28. if(!plugin)
  29. { // This is where each plugin is ending up
  30. cerr << fileName.toAscii().data() << " is not a valid plugin..." << endl;
  31. }
  32. else
  33. {
  34. cerr << fileName.toAscii().data() << " is a valid plugin" << endl;
  35. if(qobject_cast<input *>(plugin))
  36. {
  37. cerr << fileName.toAscii().data() << " is an input plugin" << endl;
  38. input * i = qobject_cast<input *>(plugin);
  39. lPluginFile << fileName;
  40. lPluginName << i->getName();
  41. lPluginDescription << i->getDescription();
  42. }
  43. }
  44. }
  45. if(!lPluginName.size())
  46. {
  47. return;
  48. }
To copy to clipboard, switch view to plain text mode 
... and the cerr output:
Qt Code:
  1. Using plugin path: /home/rich/svn/evilcpc/trunk/evilcpcconf
  2. Changed to: /home/rich/svn/evilcpc/trunk/evilcpcconf/plugins
  3. Found a file: /home/rich/svn/evilcpc/trunk/evilcpcconf/plugins/libinputVoice.so
  4. libinputVoice.so is not a valid plugin...
  5. Found a file: /home/rich/svn/evilcpc/trunk/evilcpcconf/plugins/libmenuAeon.so
  6. libmenuAeon.so is not a valid plugin...
  7. Found a file: /home/rich/svn/evilcpc/trunk/evilcpcconf/plugins/libmenuBasic.so
  8. libmenuBasic.so is not a valid plugin...
  9. Found a file: /home/rich/svn/evilcpc/trunk/evilcpcconf/plugins/libmenuItemGps.so
  10. libmenuItemGps.so is not a valid plugin...
To copy to clipboard, switch view to plain text mode 
What am I doing incorrectly in my plugin code?