PDA

View Full Version : Using dll in QT4



ankurjain
13th March 2006, 11:04
hi all,
can anybody explain me how to make and use dll in qt4.

i made a dll for doing table related operations. i wrote a simple file test.cpp/test.h (taking help of some project on net) and just inherited the QTableWidget in it.




//test.h

#ifndef QGRID_H
#define QGRID_H
#include <QtCore/qglobal.h>
#include <QTableWidget>

#ifdef Q_OS_WIN
# ifdef BUILD_QGRID
# define QGRID_EXPORT __declspec(dllexport)
# else
# define QGRID_EXPORT __declspec(dllimport)
# endif
#else
# define QGRID_EXPORT
#endif

#endif

//#include "ui_QGrid.h"

class QGrid : public QTableWidget {

public:
QGrid(QWidget *parent = 0);
};



and this is my test.cpp



//test.cpp

#include <QtGui>
#include "QGrid.h"
//#include <QMessageBox>

extern "C" QGRID_EXPORT QGrid* CreateQgrid(QWidget *parent)
{
return new QGrid(parent);
}

QGrid::QGrid(QWidget *parent)//:QTableWidget(parent)
{}




i copied the dll in the main project

here i called a function from dll CreateQgrid as follows

[QUOTE]
//main project

QLibrary lib("test");
typedef QGrid* (*ptr)(QWidget *);
ptr function = (ptr) lib.resolve("CreateQgrid");
QGrid *temp = function(this);

[QUOTE]

i've typedef'd the constructor and called it using function pointer in the program. also the functions in dll are declared as extern "C" (i don't know y, but if i use only extern or __cdecl(dllexport) the program that uses the dll crashes).

now :
1) do i have to make some other function as CreateQgrid above in dll to use some function (QGrid here) or there is some other way.

2) how to use the dll function in our program? do i have to do a typedef each time ?

please explain the procedure.

ChristianEhrlicher
13th March 2006, 11:34
Your way to access a function in the dll is wrong (this just works for c-functions but it isn't needed at all). Test.h is nearly correct. But you shouldn't use __declspec(dllexport) but Q_DECL_EXPORT / Q_DECL_IMPORT to be platform independent - there is no need to mask this with Q_OS_WIN (in fact this is wrong since mingw don't know anything about __declspec() and will not compile your code)



#ifdef BUILD_QGRID
# define QGRID_EXPORT Q_DECL_EXPORT
#else
# define QGRID_EXPORT Q_DECL_IMPORT
#endif


Your test.cpp is wrong. There is no need for CreateQgrid(QWidget *parent) because you exported the class and can access QGrid directly. Also 'extern "C"' is not needed.

In your main project you only have to include test.h and access QGrid like normal. When linking you have to link against the import lib (test.lib) created by the linker during test.dll creation

ankurjain
13th March 2006, 11:57
Thanx for the fast reply.

i did as u told ....

now when i try to use the following code in my main project:



QLibrary lib("QGrid");
QGrid *temp = new QGrid;


it gives the following error to compile ....


unresolved external symbol "public: __thiscall QGrid::QGrid(class QWidget *)" (??0QGrid@@QAE@PAVQWidget@@@Z)

also can u please tell me how can i use lib.resolve in my code

i m using MS VC++ to compile and using QT4.1.1 (sry i 4got to mention in the 1st post).

thanx in advance ...

ChristianEhrlicher
13th March 2006, 12:35
You don't need "QLibrary lib("QGrid");"

This is a linker error, not a compiler error. You have to link against test.lib which should be created when you built your test.dll. If test.lib wasn't created, you forgot to define BUILD_QGRID when you created test.dll
Do you use qmake/pro-files to create your project? If you use qmake. add 'LIBS += test' to your pro-File. Otherwise you have to add test.lib to your link command line.

lib.resolve() only works when you use plain c-functions because of name mangeling - do you really want to do this?

ankurjain
14th March 2006, 04:31
Thanx again for reply. I will explain first what i am trying to do.

I am making a dll which will give the functionality to create a table and do operations on it like excel. this dll is to used in the main project and will use all functions from the dll. This dll has to be made in such a way that it can be used in other QT projects as well.

The main project is having two tables in a form as below

http://img100.imageshack.us/img100/8205/grid8wm.th.jpg (http://img100.imageshack.us/my.php?image=grid8wm.jpg)

Now being new to qt, i tried my hand with first making only a class in a separate dll project, say it QGrid from the MS Addin for QT, and only inherited the class QTableWidget publicly.

I exported the symbol by extern "C" method i posted in above post and used it in the main project as i stated above (typedef and all that stuff).

This i studied from a sample dll project for QT. also thos method is in the docs of QLibrary.

Now u tell me how to do the things work.

my pro file for dll is as follows :



DEPENDPATH += .
INCLUDEPATH += . ../include/
TARGET = QGrid
QT = core gui
TEMPLATE = lib plugin
SOURCES += QGrid.cpp
HEADERS += QGrid.h
FORMS += QGrid.ui
RESOURCES += QGrid.qrc
CONFIG += shared
DEFINES += BUILD_QGRID
HEADERS += QGrid.h



please giv suggestions asap... i need it badly...

ChristianEhrlicher
14th March 2006, 07:37
Using 'extern "C"' and resolving on runtime is imho the worst thing you can do. If you really need to load it on runtime, create a qt-plugin... (read the docs!)

I've attached a small example to show how to use a lib.

ankurjain
16th March 2006, 04:09
Hi Chritian,
u hav given a nice example of exporting class from dll.
if i hav to export functions from dll, i used the following code ... please chk and reply if its correct or not :

in my QGrid.h file :


//test function
QGRID_EXPORT int asum(int a,int b)
{
return a+b;
}


in my project eventtable.h file :


QGRID_EXPORT int asum(int a,int b);

if i don't import the function as above, the compiler generates error that


error C2065: 'asum' : undeclared identifier


in eventable.cpp file :

i call the function directly as a local function:


int a = asum(2,5);


this on compiling the main project gives the following linker warnings :


LINK : warning LNK4049: locally defined symbol ""public: __thiscall QGrid::QGrid(class QWidget *)" (??0QGrid@@QAE@PAVQWidget@@@Z)" imported

LINK : warning LNK4049: locally defined symbol ""public: virtual __thiscall QGrid::~QGrid(void)" (??1QGrid@@UAE@XZ)" imported

LINK : warning LNK4049: locally defined symbol ""int __cdecl asum(int,int)" (?asum@@YAHHH@Z)" imported


what is the reason of these warnings. the project is working fine though.

i m using VC++ compiler ...

ankurjain
17th March 2006, 06:44
hi christian,

i somehow solved the problem, in my .pro file i previously had the line


LIBS =../service/release/QGrid


now i changed it to


LIBS=../service/release/QGrid.lib

and the warnings are gone


can u tell me wat could be the problem ... as with QGrid (and not QGrid.lib) also my program was running fine with warnings only ....

Thanx...