PDA

View Full Version : Problem with my C++ library that uses a interface class



maxoreli
30th December 2011, 02:26
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


#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


now the defintion of my library class

ItableManager.h


#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


ITableManager.cpp



#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 )



my ITableManager.pro




QT += sql

TARGET = ITableManagerPlugin
TEMPLATE = lib

DEFINES += ITABLEMANAGER_LIBRARY

SOURCES += itablemanager.cpp

INCLUDEPATH +=interface/

HEADERS += itablemanager.h\
ITableManager_global.h\


DESTDIR =../lib


so ,when i compile my program, i'm getting following errors in my application output pane

debug\tablemanagerplugin.o:-1: In function `TableManagerInterface':
TableManagerInterface.h:12: error: undefined reference to `vtable for TableManagerInterface'
debug\tablemanagerplugin.o:-1: In function `TableManagerPlugin':
tablemanagerplugin.h:8: error: undefined reference to `TableManagerInterface::~TableManagerInterface()'
:-1: error: collect2: ld returned 1 exit status


Someone can you tell me what the problem?
Thanks in advance

amleto
30th December 2011, 13:50
tablemanagerplugin.h:8: error: ...

where is this file?

TableManagerInterface.h:12 <-- This is an empty line. Are you sure that what you have posted matches EXACTLY what is compiled by you?

Spitfire
4th January 2012, 15:33
virtual void select(const QString &filter=0);
Method above is not virtual, I guess it's a mistake. Change it to pure virtual as below
virtual void select(const QString &filter)=0and the error will go away.

Otherwise if you have an interface with at least one non-pure-virtual method move implementation of the destructor to a separate file (.cpp) and it will fix the error as well.

Here's a link (http://gcc.gnu.org/faq.html#vtables) that will tell you more about it.