how to make shared objects with QT (creating .so files in linux or .dll in win32)
INTRODUCTION
-----------
if u want to have smaller executable and dont want to see all codes togather u can use .so files. and if u want to have a moduler application that changes modules by modules not totally. and if u want to have same ability in another applications u should use .so.
for example: u r developing gaim. u know gaim supports a lot of protocol ICQ/MSN/... anyway. when user dont use msn protocol it shouldnt be loaded. with this way memory will be used as small as possible.
another example: u want to develop a MSN client application. if gaim developers made that msn protocol as GPL I mean open source. and publish that libgaimmsn.so. u can use that .so and dont lose time for making a msn protocol implementation.
I hope u understood what r loadable shared libraries/objects using for.
IMPLEMENTATION
--------------
First qmake is a good tool that make life better and easier

and read QT documentation.
it is so easy to make lib***.so files with it. I havent tried it before in linux or win32 (as DLL). then I made qt_lib_try.pro file for qmake. before go on u should check that u have QTDIR enviroment exported and in PATH QTDIR/bin included.
///qt_lib_try.pro
TEMPLATE = lib
INCLUDEPATH += .
LIBS+= -lqui #this line needed by QWidgetFactory
# Input
HEADERS += myclass.h
SOURCES += myclass.cpp
CONFIG += warn_on
as u see there are 2 files will make one shared object(.so).
I want something really dynamic

and flexible. and decided to use QWidgetFactory and have a form from .ui file

if I do that I compile one time my .so file and example application which is using my .so and change everything just playing with .ui file in designer
///myclass.h
#include <qwidget.h>
#include <qwidgetfactory.h>
#include <qhostaddress.h>
#include <qsocket.h>
class MyClass
{
public:
int x;
QWidget *w;
MyClass() {
w=QWidgetFactory::create("form1.ui");
x=50;
w->show();
};
void repair(){
qDebug("haha");
};
};
///the exported function
extern "C"
{
MyClass* GetClass();
}
///myclass.cpp
#include "myclass.h"
MyClass* GetClass()
{
MyClass* cl= new MyClass();
return cl;
}
that two files will make .so file and thats job will be just open a form from constructor with .ui
we have .pro and .h and .cpp file now making lib from them for using in our example app.
qmake -o Makefile qt_lib_try.pro
make
[mascix@linmascix qt_lib_try]$ make
g++ -c -pipe -Wall -W -O2 -fomit-frame-pointer -pipe -march=i586 -mcpu=pentiumpro -fPIC -DQT_NO_DEBUG -I$QTDIR//mkspecs/default -I. -I. -I$QTDIR//include -o myclass.o myclass.cpp
rm -f libqt_lib_try.so.1.0.0 libqt_lib_try.so libqt_lib_try.so.1 libqt_lib_try.so.1.0
g++ -shared -Wl,-soname,libqt_lib_try.so.1 -o libqt_lib_try.so.1.0.0 myclass.o -L$QTDIR//lib -lqt-mt -lqui
ln -s libqt_lib_try.so.1.0.0 libqt_lib_try.so
ln -s libqt_lib_try.so.1.0.0 libqt_lib_try.so.1
ln -s libqt_lib_try.so.1.0.0 libqt_lib_try.so.1.0
as u see our shared objects ready to use. now we need an example application for using these files.
////example.cpp
#include <qapplication.h>
#include <qlibrary.h>
#include "myclass.h"
int main( int argc, char **argv )
{
QApplication a(argc,argv);
typedef MyClass* (*pf)();
pf function=(pf)QLibrary::resolve(("./libqt_lib_try.so"),"GetClass");
MyClass* cl= function();
cl->repair();
qDebug("here is our x from shared object x=%d",cl->x);
a.setMainWidget(cl->w);
return a.exec();
}
here how should we compile that example:
gcc example.cpp -I $QTDIR/include/ -lqt-mt -L $QTDIR/lib/ -L ./libqt_lib_try.so -o example
./example
haha
here is our x from shared object x=50
tataa everything ok and our application working. but u need one more thing if u r a lazy person
//form1.ui
<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
<class>Form1</class>
<widget class="QWidget">
<property name="name">
<cstring>Form1</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>231</width>
<height>154</height>
</rect>
</property>
<property name="caption">
<string>Form1</string>
</property>
<widget class="QLabel">
<property name="name">
<cstring>textLabel1</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>30</y>
<width>112</width>
<height>30</height>
</rect>
</property>
<property name="text">
<string>Mascix made me</string>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>pushButton1</cstring>
</property>
<property name="geometry">
<rect>
<x>80</x>
<y>100</y>
<width>110</width>
<height>30</height>
</rect>
</property>
<property name="text">
<string>Exit</string>
</property>
</widget>
<widget class="QLCDNumber">
<property name="name">
<cstring>lCDNumber1</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>60</y>
<width>64</width>
<height>23</height>
</rect>
</property>
</widget>
</widget>
<connections>
<connection>
<sender>pushButton1</sender>
<signal>clicked()</signal>
<receiver>Form1</receiver>
<slot>close()</slot>
</connection>
</connections>
<layoutdefaults spacing="6" margin="11"/>
</UI>