Problem with my C++ library that uses a interface class[Solved]
-
hi,i 'm creating a C++ library that inherits from an interface,but i have met some troubles during runtime.
it is my Interface class
[CODE]
#ifndef TABLEMANAGERINTERFACE_H
#define TABLEMANAGERINTERFACE_H#include<QtPlugin>
#include <QtSql/QSqlRecord>
#include <QtSql/QSqlTableModel>
#include <QtSql/QSqlDatabase>class TableManagerInterface
{private:
enum TypeModels { ReadOnlyModel,ReadWriteModel,RelationnalModel};
public:
virtual ~TableManagerInterface() {}virtual void setDatabase(const QSqlDatabase &database)=0; virtual void setTable(const QString &tablename)=0; virtual void select(const QString &filter=0); virtual void insertRecord(const QSqlRecord &record)=0; //virtual void editRecord(const QSqlRecord &record) =0; // virtual void deleteRecord(const QSqlRecord &record) =0;
};
QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(TableManagerInterface,
"com.MaxSoft.Plugin.TableManagerInterface/1.0")QT_END_NAMESPACE
#endif
[/CODE]now the defintion of my library class
ItableManager.h
[CODE]
#ifndef ITABLEMANAGER_H
#define ITABLEMANAGER_H#include "ITableManager_global.h"
#include <QtGui/QStylePlugin>
#include<QtSql>
#include "interface/TableManagerInterface.h"class ITABLEMANAGERSHARED_EXPORT ITableManager :public QObject,public TableManagerInterface
{
Q_OBJECT
Q_INTERFACES(TableManagerInterface)public:
ITableManager();
virtual ~ITableManager() {}private:
QSqlDatabase db;
QSqlTableModel *model;
QMap<int,QString> mapKey;
public:
void setDatabase(const QSqlDatabase &database);
void setTable(const QString &tablename);
void setPrimaryKeys(QMap<int, QString> map);
void select(const QString &filter=0);
QSqlRecord record() const;
void insertRecord(const QSqlRecord &record);signals:
public slots:
};
#endif // ITABLEMANAGER_H
[/CODE]ITableManager.cpp
[CODE]
#include "itablemanager.h"
#include<QMessageBox>ITableManager::ITableManager()
{}
/*!
Cette méthode permet de récupérer une instance de laconnexion
à une base de donnée
*/
void ITableManager::setDatabase(const QSqlDatabase &database)
{
this->db=database;
}/*!
informe sur la table et ses champs
*/
void ITableManager::setTable(const QString &tablename)
{
model= new QSqlTableModel(0,this->db);
model->setTable(tablename);
}/*!
charge le model avec les lignes
*/
void ITableManager::select(const QString &filter)
{
model->setFilter(filter);
if( !model->select() )
qDebug()<<" Lignes non chargées";
}/*!
retourne une enregistrement contenant les infos à
propos des colonnes(champs) de la table
*/
QSqlRecord ITableManager::record() const
{
return model->record();
}/*!
spécifie les clés primaires et leurs types
*/void ITableManager::setPrimaryKeys(QMap<int, QString> map)
{
mapKey = map;
}/*!
*/
void ITableManager::insertRecord(const QSqlRecord &record)
{//on verifie si la clé existe QString filter="WHERE "; QMapIterator<int,QString> i(mapKey); while (i.hasNext()) { i.next(); // cout << i.key() << ": " << i.value() << endl; if( i.value()=="int"){ filter += record.fieldName(i.key()) + "=" + record.value(i.key()).toInt()+ " "; } else if (i.value()=="String") { filter += record.fieldName(i.key()) + "='" + record.value(i.key()).toString() +"' "; } else if (i.value()=="Date") { filter += record.fieldName(i.key()) + "='"+record.value(i.key()).toDate().toString("dd/MM/yyyy")+"' "; } else if (i.value()=="Double") { filter += record.fieldName(i.key()) + "=" +record.value(i.key()).toDouble() + " "; } if( i.hasNext()) filter +=" AND "; } this->select(filter); if (model->rowCount() != 0) QMessageBox::warning(0,tr("Erreur Insertion"),tr("Présence de doublons")); else{ if( model->insertRecord(-1,record) ) QMessageBox::information(0,tr("Insertion"),tr("Enregistré")); else{ QMessageBox::critical(0,tr("Erreur Insertion"),tr("Echec de L'enregistrement! <br> " "Vérifiez les valeurs..")); qDebug()<< model->lastError().text(); } }
}
Q_EXPORT_PLUGIN2(ITableManagerPlugin,ITableManager)
[/CODE]
[CODE]
QT += sql
TARGET = ITableManagerPlugin
TEMPLATE = libDEFINES += ITABLEMANAGER_LIBRARY
SOURCES += itablemanager.cpp
INCLUDEPATH +=interface/
HEADERS += itablemanager.h
ITableManager_global.h\DESTDIR =../lib
[/CODE]so ,when i compile my program, i'm getting following errors in my application output pane
debug\itablemanager.o:-1: In function
ITableManager': itablemanager.cpp:8: error: undefined reference to
TableManagerInterface::~TableManagerInterface()'
debug\itablemanager.o:-1: In functionTableManagerInterface': TableManagerInterface.h:11: error: undefined reference to
vtable for TableManagerInterface'
:-1: error: collect2: ld returned 1 exit status
[/B]*Someone can you tell me what the problem?
Thanks in advance -
You showed the source code. Object code is what the compiler produces. It's glued together by the linker to a runnable application (or a library).
Just by including the header file into another source file does not necessarily produce some object code that can be linked. I recommend to put the dummy implementation of the interface into a separate C++ file (.cpp). You will have to link its object code (xxx.o) to your project or - better - create a library out of it that you link against.
-
[quote author="Volker" date="1325265231"]You showed the source code. Object code is what the compiler produces. It's glued together by the linker to a runnable application (or a library).
Just by including the header file into another source file does not necessarily produce some object code that can be linked. I recommend to put the dummy implementation of the interface into a separate C++ file (.cpp). You will have to link its object code (xxx.o) to your project or - better - create a library out of it that you link against.[/quote]
How do i will do that,making dummy implementation.
Create an another source file nammed 'TableManagerInterface.cpp' and put this code?
@
#include "TableManagerInterface.h"
@
i try it but dont work.
Please lead me to do it..
thanks in advance -
i did what you said and compilation works fine.
Now i want to use my C++ library in another project .this is global structure of my project.
-Folder Dao(Dao.pro,
Folder ITableManager(itablemanager.pro,itablemanager.h,itablemanager.cpp,
Folder interface(TableManagerInterface.h,TableManagerInterface.cpp))
)-Folder ui(project which uses library class)
(
ui.pro, dialogArtiste.cpp,dialogArtiste.h
)Now i edit the * ui.pro* file for using library.
@QT +=sql
SOURCES +=
main.cpp#folders
include(client/client.pri)
include(contrat/contrat.pri)
include(reservation/reservation.pri)
include(suivi_formation/suivi_formation.pri)
include(suivi_master/suivi_master.pri)
include(ventes/ventes.pri)#library
DEPENDPATH += Dao/ITableManager
INCLUDEPATH += Dao/ITableManager
LIBS += -LDao/ITableManager/debug -lITableManager@
-in some parts in dialogArtiste.h i m putting following codes(i include 'itablemanager.h' and declare a 'ITableManager object')
@
#ifndef DIALOGARTISTE_H
#define DIALOGARTISTE_H#include "ui_dialogartiste.h"
//include for using ITableManager class
#include "itablemanager.h"class DialogArtiste : public QDialog, private Ui::DialogArtiste
{
Q_OBJECTpublic:
explicit DialogArtiste(QWidget *parent = 0);protected:
void changeEvent(QEvent *e);
private:
ITableManager *manager; // declare a ITableManager(class of my library)
};#endif // DIALOGARTISTE_H
@
then when i compile, i'm getting error like:
:-1: error: cannot find -lITableManager
i think that i dont put an appropriate path of my library.
What do i should do?
Thanks in advance.[quote author="Volker" date="1325338845"]You will have to move the empty body of the destructor to the .cpp file. And either include that file into your plugin project, or make it a library that you link against. I don't have a complete example at hand.[/quote]
-
[quote author="maxoreli" date="1325660608"]
then when i compile, i'm getting error like::-1: error: cannot find -lITableManager
i think that i dont put an appropriate path of my library.
What do i should do?
Thanks in advance.
[/quote]Search the location of libTableManager.{a,so,lib,dylib} and add this directory to the LIBS variable:
@
LIBS += -L/path/to/your/lib
@ -
ok,i have done it like that.
@
DEPENDPATH += C:/Users/MAXORELI/Documents/QtPrograms/ENIOLASYST/Dao/ITableManager
INCLUDEPATH += C:/Users/MAXORELI/Documents/QtPrograms/ENIOLASYST/Dao/ITableManager
LIBS += -L/C:/Users/MAXORELI/Documents/QtPrograms/ENIOLASYST_Debug/Dao/lib/libITableManagerPlugin.a
@
However, i m getting following error:
\dialogartiste.o:-1: In functionDialogArtiste': \dialogartiste.cpp:8: error: undefined reference to
_imp___ZN13ITableManagerC1Ev'
\dialogartiste.cpp:8: error: undefined reference to `_imp___ZN13ITableManagerC1Ev'what happens i dont understand
[quote author="Volker" date="1325691249"]
[quote author="maxoreli" date="1325660608"]
then when i compile, i'm getting error like::-1: error: cannot find -lITableManager
i think that i dont put an appropriate path of my library.
What do i should do?
Thanks in advance.
[/quote]Search the location of libTableManager.{a,so,lib,dylib} and add this directory to the LIBS variable:
@
LIBS += -L/path/to/your/lib
@
[/quote] -
That's basic C/C++ magic
- -L (uppercase L) adds the path to a directory containing libraries
- -l (lowercase l) add a library to the link step
it is search in the standard system lib paths and that added via -L to your project
I leave it as an exercise to you to split your line up into two parts.
-
-in fact my lines aren't splitted in my .pro file, they were splitted when i have posted the reply.
this is what happens.
when i just declare an ITableManager in .h file ,compilation works fine.@
#ifndef DIALOGARTISTE_H
#define DIALOGARTISTE_H#include "ui_dialogartiste.h"
#include "itablemanager.h"class DialogArtiste : public QDialog, private Ui::DialogArtiste
{
Q_OBJECTpublic:
explicit DialogArtiste(QWidget *parent = 0);protected:
void changeEvent(QEvent *e);
private:
ITableManager *manager;
};#endif // DIALOGARTISTE_H
@after when i instantiate the ITableManager in .cpp, compilation displays errors:
@
#include "dialogartiste.h"DialogArtiste::DialogArtiste(QWidget *parent) :
QDialog(parent)
{
setupUi(this);manager=new ITableManager;
}
@Errors:
-dialogartiste.cpp:8: error: undefined reference to_imp___ZN13ITableManagerC1Ev' -dialogartiste.cpp:8: error: undefined reference to
_imp___ZN13ITableManagerC1Ev'
[quote author="Volker" date="1325780670"]That's basic C/C++ magic- -L (uppercase L) adds the path to a directory containing libraries
- -l (lowercase l) add a library to the link step
it is search in the standard system lib paths and that added via -L to your project
I leave it as an exercise to you to split your line up into two parts.[/quote]
-
oh,thanks you so much Volker,really speaking i was so stupid for not thinking to it,now compilation works fine,but isn't it some parts where it is explained in documentation? if yes,send me link,or you have an another link which explains this notion.
How to mark this thread like resolved?
Thanks for reading again.
[quote author="Volker" date="1325810603"]@
LIBS += LC:/Users/MAXORELI/Documents/QtPrograms/ENIOLASYST_Debug/Dao/lib
LIBS + -lITableManagerPlugin
@
[/quote] -
It's not in the Qt docs (despite some usage in examples). It's compiler dependent and documented with those, although most tool chains use -l and -L for the libs and lib paths, and -I for include paths. I don't know of any popular compiler that doesn't support this (at least additionally to some "native" switches like /xxx). It should be explained detailed in quite all decent introductions into C/C++ programming.
To mark a thread as solved, just go to your very first post that opened the thread, click on the edit link right to it (just below your username and avatar) and prepend [Solved] to your topic, that's all. You might want to add a tag "solved" too.