PDA

View Full Version : Deploy a Library



cafu1007
14th June 2010, 19:20
Hi all,

I am trying to deploy a library developed with Qt (is meant to comunicate with a server thru TCP/ip QSockets). I trying to use this dll from a MFC application, i have used the dll the function call works fines but it seems that that the slot are no being called.

I have start a Thread that ask for qApp if there is not, one is created and exec is called. But i seem that still dont work.

My idea is that when the object that have signal and slot is created the qApp.exec(); is still no executed. I have observed this behavior in the log file.

is there a way to know if qApp has the eventLoop running?
which other way can i use, to achieve to use this dll from application that are not develop with Qt?

Thanks for the answer.

PD: i know this is not a mfc forum, but think this is a general problem to be able to deploy a dll that can be use by a external application no forcing the user to use Qt.

wysota
15th June 2010, 02:20
I'd have to see the code to be able to suggest a proper solution but a dirty workaround is to periodically call QApplication::processEvents() from within MFC event loop.

cafu1007
15th June 2010, 09:09
qint32 ClassD::connectToServer(QString IP, qint32 port)
{
qDebug() << "connectToServer";
client = new CCltClient(this);
connect(client, SIGNAL(signalConnectedToServer()), this, SLOT(slotConnectedToServer()));
if (!client->connectToServer(IP, port))
{
return FORMAT_ERROR;
}
return OK;
}
void ClassD::slotConnectedToServer()
{
qDebug() << "slotConnectedToServer";
}
void Thread::close()
{
emit Kill_me();
}
void Thread::run()
{
qDebug("run");
if (!qApp)
{
qDebug("no application running");
int argc = 1;
char *argv[] =
{ "setup", NULL };
QApplication a(argc, argv);
a.connect(this, SIGNAL(Kill_me()), &a, SLOT(quit()));
qDebug("start running");
a.exec();
qDebug("application end");
}
}

static ClassD *pToFunc;
Thread t;
extern "C" __declspec(dllexport) int func1(void)
{
t.start();
pToFunc = new ClassD();
return pToFunc->connectToServer("127.0.0.1", 9190);
}


I can connect to server and when i use the dll with the A Qt application Gui the slot is called but from the mfc does not.

"I have modified the run"

wysota
15th June 2010, 10:34
You are creating a local QApplication object that goes out of scope immediately afterwards. The run() method doesn't make sense too - "if there is no qApp, call qApp".

cafu1007
15th June 2010, 10:48
HI Thanks for the answer i have fixed that in the code post that is how i am using it, but i got a warning "QApplication was not created in the main() thread.", and still does call the slot, i have tried also to decalre a as global pointer make new in the run but also do not work, sorry the previous mistake i was cutting and pasting.

wysota
15th June 2010, 10:52
So what's the problem now?

cafu1007
15th June 2010, 10:54
the problem is the same the slot are not being called

cafu1007
15th June 2010, 11:06
QApplication *a;
void Thread::run()
{
qDebug("run");

if (!a)
{
qDebug("no application running");
int argc = 1;
char *argv[] =
{ "setup", NULL };
a = new QApplication(argc, argv);
QObject::connect(this, SIGNAL(Kill_me()), a, SLOT(quit()));
qDebug("start running");
a->exec();
qDebug("application end");
}
else
{
QObject::connect(this, SIGNAL(Kill_me()), a, SLOT(quit()));
qDebug("start running");
a->exec();
qDebug("application end");
}
}

static ClassD *pToFunc;
Thread t;
dllExport int func1(void)
{
if (!qApp)
{
qDebug("no application running");
int argc = 1;
char *argv[] =
{ "setup", NULL };
a = new QApplication(argc, argv);
}
qInstallMsgHandler(debugWinMsgHandler);
t.start();
t.setPriority(QThread::HighPriority);
qDebug() << "func1";

pToFunc = new ClassDl();
return pToFunc->connectToServer("127.0.0.1", 9190);
}

Like this work, i suppose cause of the priority of the thread the exec is called faster so when the function connect to server is called there is an application running, also i got this warning "QApplication::exec: Must be called from the main thread".

back to one question how can i assure that qApp is being executing?(tha the called to exec() was done).

Thanks

I am not calling the thread to start the Qapplication .exec(). Now it works. Is strange that there is a Qt application running, and the qApp is not recognized and a new one is created, as my understanding the QApllication shoul be a singlenton,isn´t it? the CCltClient is a thread and when a connect to server is called the thread is started. Is there no need to call qApp.exec() so it start to recognize the signals? i got a bit confused.



dllExport int func1(void)
{
qInstallMsgHandler(debugWinMsgHandler);
if (!qApp)
{
qDebug("no application running");
int argc = 1;
char *argv[] =
{ "setup", NULL };
a = new QApplication(argc, argv);
}
qDebug() << "func1";
pToFunc = new ClassD();
return pToFunc->connectToServer("127.0.0.1", 9190);
}

this is how it looks the func1 now.

wysota
15th June 2010, 12:05
Thread can't be a subclass of QThread, this doesn't make sense. If it is a subclass of QThread then call QThread::exec() instead of QApplication::exec() (and create the application object in the main thread then). Otherwise use native means to create a thread and try instantiating the application object there.

cafu1007
15th June 2010, 12:16
Sorry i do not understand. shall i leave the the last form of func1, but also call t.start() and in the run call exec(). and leave it running for the time tha the application need it. is this what you mean?.. and what about the singleton of QApplication, why a new one is created, or at least why is no reconigzed as exiting....

and as i said before i not calling any longer QApplication::exec(). but in the CCltClient in the run i call QThread::exec(). is this why it works?

A last QApplication *a should remain globlal so it does not go out of scope....

Thanks....

wysota
15th June 2010, 12:22
Sorry i do not understand. shall i leave the the last form of func1, but also call t.start() and in the run call exec(). and leave it running for the time tha the application need it. is this what you mean?..
You need an event loop. Qt doesn't care if it is going to be the main event loop (QApplication::exec()) or a per-thread loop (QThread::exec()) as long as there is something to process events. So choose either approach and stick with it.


and what about the singleton of QApplication, why a new one is created, or at least why is no reconigzed as exiting....
Application object is not created automatically. You have to create it yourself (reglardless if you intend to use a per-thread event loop or the main event loop -- the application object has to exist somewhere).

cafu1007
15th June 2010, 12:33
Application object is not created automatically. You have to create it yourself (reglardless if you intend to use a per-thread event loop or the main event loop -- the application object has to exist somewhere).

Yeah but there a Qt Gui running so it should somewhere in the system or i am wrong

wysota
15th June 2010, 13:38
You said it was an MFC app. Now I'm confused.

cafu1007
15th June 2010, 13:43
yeah mfc app is using the dll that i have show the code. but in the same system there is also a gui appliction which was developed using Qt and QWidgets...

wysota
15th June 2010, 13:57
Each application needs its own application object.

cafu1007
15th June 2010, 14:01
OK now i understand, thanks.

HI, one last question if i am able to run the dll from a mfc, thats means that the dll can be used with any c++ compiler or there is some exceptions or how do i know that

wysota
15th June 2010, 14:35
It can be used with the same type (and possibly version) of compiler it was compiled with. You can't use MinGW compiled DLL with MSVC compiled application (at least not directly).

cafu1007
15th June 2010, 14:41
but i am using to compile the dll MinGW, and to compiled the gui MFC Visual C++ 2005. and it works

wysota
15th June 2010, 14:57
It's hard for me to believe it as MinGW and MSVC use different name mangling schemes and create import libraries with different (incompatible) filenames. Check if you are really using two different compiler families.

cafu1007
15th June 2010, 15:05
when i used the libCDll.a file i rename it to CDll.lib and it works.

cafu1007
26th August 2010, 18:57
Hello there,

I am having problems with the deploying of the lybrary, it work properly if i use the QApplication, but i would like to use QCoreApplication so i have less libraries to deploy. but when i changed to QCoreApplication, the slots are not being called. The run of the thread is called (using start) and exec() of the thread is called within the run, but nothing is happening.

Is there any reason for this, do i have to stick to QApplication.

Thanks in advance for the help.

Cafu

cafu1007
27th August 2010, 09:12
Hi,


Should i start a new thread?


Carlos

wysota
29th August 2010, 21:14
There has to be something wrong in your code or compilation cycle. QApplication only adds the GUI layer to QCoreApplication.

cafu1007
30th August 2010, 09:06
Hi wysota,

it works after i add to the constructor moveToThread(this); i still do not understand exactly what this line does but after that it works with QCoreApplication. Could you explain to me?

wysota
30th August 2010, 09:13
it works after i add to the constructor moveToThread(this); i still do not understand exactly what this line does but after that it works with QCoreApplication.
The docs can - QObject::moveToThread().

cafu1007
30th August 2010, 09:20
ok, i have read then and i dont have it so clear.

but you confirm that this is what it was missing?, why was working before? QApplication set affinity of the thread or waht was going on?

i like to get things to work, but i also like to understand how it works....

wysota
30th August 2010, 09:37
but you confirm that this is what it was missing?
No, I don't.


why was working before? QApplication set affinity of the thread or waht was going on?
I have not seen your code so how could I confirm anything? If it does work after adding moveToThread then you should probably read about thread affinity in Qt and explanations why your code shouldn't look like what it looks like now.

You can probably start here: You're doing it wrong (http://labs.trolltech.com/blogs/2010/06/17/youre-doing-it-wrong/).

cafu1007
30th August 2010, 09:59
Is very interesting, so actually i should not make a class to inherit form QThread since the only thing that i need is a exec() to handles the the processing (signals and slots), but with this aproach that is proposed in Threading without the headache (http://labs.trolltech.com/blogs/2006/12/04/threading-without-the-headache/) then i don need to use mutex and sync why is that??(this is propose there)

wysota
30th August 2010, 10:10
Again, I have not seen what your code does so I can't suggest an approach. I'm merely pointing out what you are doing wrong. It could be that you don't need any threads at all.

cafu1007
31st August 2010, 18:07
Hi there,

If use a->moveToThread (thread); the children of a also move to thread or not?

wysota
31st August 2010, 19:02
Yes, they do.