undefined reference in a shared class between plugin and app.
-
Hi all,
I want to use a class shared between plugins and a main app.
But when I try to compil, I have this error:plugins\plugin01\plugin01.cpp:13: erreur : undefined reference to `CommonParameter::CommonParameter()'
I must have a LIBS problem somewhere in a .pro file or something else
Thanks in advance,
FilipeCode:
/testplugin.pro
TEMPLATE = subdirs SUBDIRS += \ src \ plugins
/src/src.pro
TARGET = testplugin DESTDIR = ../bin TEMPLATE = app QT -= gui HEADERS += \ iplugin.h \ commonparameter.h SOURCES += \ main.cpp \ commonparameter.cpp qtHaveModule(uitools):!embedded: QT += uitools else: DEFINES += QT_NO_UITOOLS build_all:!build_pass { CONFIG -= build_all CONFIG += release } CONFIG += console CONFIG -= app_bundle
/src/iplugin.h
#ifndef IPLUGIN_H #define IPLUGIN_H #include <QtPlugin> #include <commonparameter.h> class QString; class IPlugin { public: virtual ~IPlugin() {} virtual QString name() const = 0; virtual CommonParameter *parameter() = 0; }; #define IPlugin_iid "AntunesFilipe.TestPlugin.IPlugin" Q_DECLARE_INTERFACE(IPlugin, IPlugin_iid) #endif // IPLUGIN_H
/src/main.cpp
#include <QCoreApplication> #include <QTextStream> #include <QDir> #include <QPluginLoader> #include "iplugin.h" #include "commonparameter.h" int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); // Find plugins located in a repository folder and load them... QDir pluginsDir = QDir(qApp->applicationDirPath()); pluginsDir.cd("plugins"); foreach (QString fileName, pluginsDir.entryList(QDir::Files)) { QPluginLoader loader(pluginsDir.absoluteFilePath(fileName)); QObject *plugin = loader.instance(); if (plugin) { IPlugin *iPlugin = qobject_cast<IPlugin *>(plugin); if (iPlugin) { QTextStream(stdout) << "> Plugin name:" << iPlugin->name() << endl; // !!! Waiting for: Fix undefined reference to CommonParameter::CommonParameter() // CommonParameter *param = plugin->parameter(); // QTextStream(stdout) << " user:" << param->userName() << endl; // QTextStream(stdout) << " password:" << param->password() << endl; } } } return 0; }
Here the "sharded" class:
/src/commonparameter.h#ifndef COMMONPARAMETER_H #define COMMONPARAMETER_H #include <QString> class CommonParameter { public: CommonParameter(); void setUserName(const QString& name); void setPassword(const QString& password); QString userName() const; QString password() const; private: QString m_userName; QString m_password; }; #endif // COMMONPARAMETER_H
/src/commonparameter.cpp
#include "commonparameter.h" CommonParameter::CommonParameter(){} void CommonParameter::setUserName(const QString& name) { m_userName = name; } void CommonParameter::setPassword(const QString& password) { m_password = password; } QString CommonParameter::userName() const { return m_userName; } QString CommonParameter::password() const { return m_password; }
And a plugin:
/plugins.proTEMPLATE = subdirs SUBDIRS += \ plugin01 \
/plugins/plugin01/plugin01.pro
TEMPLATE = lib CONFIG += plugin QT += widgets INCLUDEPATH += ../../src HEADERS += plugin01.h SOURCES += plugin01.cpp TARGET = $$qtLibraryTarget(plugin01) DESTDIR = ../../bin/plugins
/plugins/plugin01/plugin01.h
#ifndef PLUGIN01_H #define PLUGIN01_H #include <QObject> #include <QtPlugin> #include <iplugin.h> class Plugin01 : public QObject, IPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "AntunesFilipe.TestPlugin.Plugin01.IPlugin" FILE "plugin01.json") Q_INTERFACES(IPlugin) public: Plugin01(); QString name() const Q_DECL_OVERRIDE; CommonParameter *parameter() Q_DECL_OVERRIDE; }; #endif // PLUGIN01_H
/plugins/plugin01/plugin01.cpp
#include "plugin01.h" #include <QWidget> Plugin01::Plugin01(){} QString Plugin01::name() const { return QString ("My Plugin 01"); } CommonParameter *Plugin01::parameter() { CommonParameter *param = new CommonParameter(); // ?!? <-- undefined reference to `CommonParameter::CommonParameter()' param->setUserName(QString ("TEST")); param->setPassword(QString ("123456")); return param; }
-
Hi and welcome to devnet,
Did you base your application on the echo plugin example ?
-
Hi SGaist
Yes I have based my application on echo plugin and Plug & Paint example.
Under windows with mingw, I can not compile the project, I have this message:
plugins\plugin01\plugin01.cpp:13: erreur : undefined reference to `CommonParameter::CommonParameter()'
Under linux, with g++(4.8.5) the compilation is done but when I execute, I have this message:
./testplugin: symbol lookup error: ???/plugins/libplugin01.so: undefined symbol: _ZN15CommonParameterC1Ev
In my first post, I made a mistake in the copy of the code:
src/main.cpp -- CommonParameter * param = plugin->parameter(); has to be replaced by ++ CommonParameter * param = iPlugin->parameter();
-
I am not sure of my "hack" but..it works if I add this line in my .pro application:
QMAKE_LFLAGS += -rdynamic
But Why ?!?
-
The problem you are having is that you are using a class that must be known to both your application and plugin. The clean way to do that is to have a library implementing the stuff that is used in both and link each to it.
Basically add another sub-project for a library that will contain CommonParameter.
-
Thank You SGaist
I think I will keep my current "dirty way", after all my application is the common module. -
Well...I confirm. It is necessary to cut the application in sub-project.
-rdynamic is not supported by OSX and Windows (!= ELF format) -
@Filipe-Antunes said in undefined reference in a shared class between plugin and app.:
-rdynamic is not supported by OSX and Windows (!= ELF format)
As is expected. The ABI on Windows is different enough and symbol resolution is done at link-time so it couldn't work. Follow @SGaist's advice and export the common classes from a library; that's the reason libraries were invented in the first place.
Kind regards.