PDA

View Full Version : Undefined reference



eekhoorn12
6th January 2011, 14:20
Hey all,

I am trying to create a plugin for my program so i created a abstract class for an interface, i followed the echoplugin example (http://doc.trolltech.com/4.7/tools-echoplugin.html). But the compiler keeps complaining about an "undefined reference to `vtable for ScrapperInterface'".

This is the complete error i get:

debug/moc_themoviedb.o: In function `~ScrapperInterface':
g:\projects\DuneInterface-build-desktop\ScrapperPlugins\TheMovieDb/../../../DuneInterface/movieWall/scrapperinterface.h:30: undefined reference to `vtable for ScrapperInterface'
collect2: ld returned 1 exit status
mingw32-make[3]: *** [debug/scrapperplugind.dll] Error 1
mingw32-make[2]: *** [debug] Error 2
mingw32-make[1]: *** [sub-TheMovieDb-make_default] Error 2
mingw32-make: *** [sub-ScrapperPlugins-make_default] Error 2
The process "E:\Qt\2010.05\mingw\bin\mingw32-make.exe" exited with code 2.
Error while building project DuneInterface (target: Desktop)
When executing build step 'Make'


This is the interface i have created:


#ifndef SCRAPPERINTERFACE_H
#define SCRAPPERINTERFACE_H

#include <QString>

#include "moviedetails.h"

class ScrapperInterface
{
public:
virtual ~ScrapperInterface() {}
virtual QString siteName() = 0;
virtual QString siteAddress() = 0;
virtual int getMovieDetails(QString movieTitle) = 0;

signals:
virtual int movieData();
};

Q_DECLARE_INTERFACE(ScrapperInterface,
"Esquirol.Plugin.Scrapper/1.0");
#endif // SCRAPPERINTERFACE_H


And this is the code for the plugin that implements the interface:
.h


#ifndef THEMOVIEDB_H
#define THEMOVIEDB_H

#include <QString>
#include <QObject>
#include <QXmlStreamReader>
#include <QtNetwork>

#include "themoviedb.h"
#include "scrapperinterface.h"
#include "moviedetails.h"

class TheMovieDb : public QObject, ScrapperInterface
{
Q_OBJECT
Q_INTERFACES(ScrapperInterface)

public:
~TheMovieDb() {}
QString siteName();
QString siteAddress();
int getMovieDetails(QString movieTitle);

signals:
int movieData();

public slots:
void replyFinished(QNetworkReply *reply);

private:
void fetch();

static const QString apiKey() { return "text"; }

QXmlStreamReader xml;
QNetworkAccessManager http;
};

#endif // THEMOVIEDB_H

.cpp


#include "themoviedb.h"
#include <QDebug>

QString TheMovieDb::siteName()
{
return "themoviedb.org";
}

QString TheMovieDb::siteAddress()
{
return "http://www.themoviedb.org";
}

int TheMovieDb::getMovieDetails(QString movieTitle)
{
qDebug() << "int TheMovieDb::getMovieDetails(QString movieTitle)";

return 0;
}

void TheMovieDb::replyFinished(QNetworkReply *reply)
{
qDebug() << "void TheMovieDb::replyFinished(QNetworkReply *reply)";
}

I know that an undefined reference means that i still have to implement one function but i thought i implemented everything the interface specifies.

Hope you can help me

Regards,
Marcel

high_flyer
6th January 2011, 14:47
Signals and slots can only be used with QObject subclasses, which call the Q_OBJECT macro.
See your ScrapperInterface class - its not a QObject, and it doesn't call the Q_OBJECT macro, and that is the reason for the error you are getting.
I actually never tried putting signals/slots in an interface, so I am not even sure it will work for you (the plugin framework) if you do that, but you can try.
EDIT:
Now that I think of it, it should not work, since as soon as you subclass a non abstract class (QObject) your interface is not an interface any more.

You will have to implement the signal slots in the object that implement the interface.

eekhoorn12
6th January 2011, 15:45
Thanks, that problem is now fixed, but i still can't seem to load my plugin.

K Fixed the problem that was stated below. Forgot the Q_EXPORT_PLUGIN2 line.


When i try to load the plugin i get the error:

"The file 'G:/projects/DuneInterface-build-desktop/movieWall/debug/scrapperplugind.dll' is not a valid Qt plugin."

I load the plugins with the following code:

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);

QDir pluginsDir(qApp->applicationDirPath());

qDebug() << pluginsDir;
foreach (QString filename, pluginsDir.entryList(QDir::Files))
{
qDebug() << filename;
qDebug() << pluginsDir.absoluteFilePath(filename);
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(filename) );
QObject *plugin = pluginLoader.instance();
qDebug() << pluginLoader.errorString();
if (plugin) {
qDebug() << "2";
scrapperInterface = qobject_cast<ScrapperInterface *>(plugin);
if(scrapperInterface)
{
qDebug() << "3";
}
}
}
}

which gives the following output:

QDir( "G:/projects/DuneInterface-build-desktop/movieWall/debug" , nameFilters = { * }, QDir::SortFlags( Name | IgnoreCase ) , QDir::Filters( Dirs|Files|Drives|AllEntries ) )
"main.o"
"G:/projects/DuneInterface-build-desktop/movieWall/debug/main.o"
"The file 'G:/projects/DuneInterface-build-desktop/movieWall/debug/main.o' is not a valid Qt plugin."
"mainwindow.o"
"G:/projects/DuneInterface-build-desktop/movieWall/debug/mainwindow.o"
"The file 'G:/projects/DuneInterface-build-desktop/movieWall/debug/mainwindow.o' is not a valid Qt plugin."
"moc_mainwindow.cpp"
"G:/projects/DuneInterface-build-desktop/movieWall/debug/moc_mainwindow.cpp"
"The file 'G:/projects/DuneInterface-build-desktop/movieWall/debug/moc_mainwindow.cpp' is not a valid Qt plugin."
"moc_mainwindow.o"
"G:/projects/DuneInterface-build-desktop/movieWall/debug/moc_mainwindow.o"
"The file 'G:/projects/DuneInterface-build-desktop/movieWall/debug/moc_mainwindow.o' is not a valid Qt plugin."
"movieWall.exe"
"G:/projects/DuneInterface-build-desktop/movieWall/debug/movieWall.exe"
"The file 'G:/projects/DuneInterface-build-desktop/movieWall/debug/movieWall.exe' is not a valid Qt plugin."
"scrapperplugind.dll"
"G:/projects/DuneInterface-build-desktop/movieWall/debug/scrapperplugind.dll"
"The file 'G:/projects/DuneInterface-build-desktop/movieWall/debug/scrapperplugind.dll' is not a valid Qt plugin."
G:\projects\DuneInterface-build-desktop\movieWall\debug\movieWall.exe exited with code 0

Here scrapperplugind.dll is the plugin i wish to load.

I was looking the code while debugging and think i found why it doesn't work.

In the isPlugin function Qt loads the settings from the library and should load with which version of Qt it is build. But it doesn't find that information and i don't know why.