PDA

View Full Version : Application Library with Qt



Exetra
24th December 2012, 16:38
Hello, i try to port a DLL i made in C++ (Win32, without MFC) to Qt but it's a bit hard.

My DLL is loaded by LoadLibrary from a non-Qt application. But even if it's Qt is portable, it have serious problems with some standards of Windows :|
Actually, i just want to load my QtGui and handle it like any Qt application. Since the entry point DllMain must return a value to continue, i thought i should make a thread to load it. Here is my problem. In this code :


#include "test_ui.h"
#include <windows.h>
#include <process.h>
#include <QApplication>
#include <QMessageBox>

void StartThread();

BOOL WINAPI DllMain( HMODULE hModule, DWORD dwReason, LPVOID /*lpvReserved*/ )
{
if (dwReason == DLL_PROCESS_ATTACH)
{
DisableThreadLibraryCalls(hModule);
// MessageBoxA(NULL, "Test DllMain", NULL, NULL);
// QMessageBox::information(0, "Test", "Test Qt");
// QtConcurrent::run(StartThread);
//_beginthread((void(*)(void*))StartThread,NULL,NULL );
}
return TRUE;
}

void StartThread()
{
MessageBoxA(NULL, "app test", "app test", NULL);
}

The MessageBoxA in the DllMain works perfectly, the QMessageBox doesn't, the QtConcurrent neither, and same way for _beginthread.
I tried by the CreateThread function :


printf("TestThr address : 0x%.8X\n", (DWORD)TestThr);
HANDLE hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)Tes tThr, NULL, NULL, NULL);
printf("CreateThread return : %d - GetLastError : %d\n", hThread, GetLastError());

The console returned me this :


TestThr address : 0x6F761010
CreateThread return : 380 - GetLastError : 6

The GetLastError return ERROR_INVALID_HANDLE while the CreateThread return me an handle, of course the thread is absolutely not loaded ...
I wanted to try with QtWinMigrate (http://qt.gitorious.org/qt-solutions/qt-solutions/trees/master/qtwinmigrate), but it's absolutely not for Qt5 cause there is always much errors.

I tried with this code : http://stackoverflow.com/a/11056698

Actually my GUI is loaded EXCEPT :

The dll don't load into the application it should be, but with another one (AutoIt script) it does
The GUI events are not handled at all, except if i minimize then maximize the UI (sort of repaint)


Well i think i said everything, i use Qt5 final, building with MSVC2010.
I hope you could help me to get this working.

amleto
24th December 2012, 16:48
My DLL is loaded by LoadLibrary from a non-Qt application.
qt widgets are not going to work without a qt event loop - normally from a qt application


Actually, i just want to load my QtGui and handle it like any Qt application
then you need a qt application, not a non-qt app and a qt dll.

Exetra
24th December 2012, 16:56
qt widgets are not going to work without a qt event loop - normally from a qt application

Then it should be possible to manually create the event loop.
Some ppl already did it but they never explain how.

wysota
24th December 2012, 17:02
Create a QApplication object and run exec() on it.

Exetra
24th December 2012, 17:17
Create a QApplication object and run exec() on it.

As you can see i wrote:

I tried with this code : http://stackoverflow.com/a/11056698

The QApplication is created, the GUI also but it's not handled at all

wysota
24th December 2012, 17:38
Well I don't know what you tried. I know what you are supposed to do. If you give me code you tried then I can respond to it. If you give me code of some class someone has written, I don't know how you expect me to answer. Apparently your code differs from theirs if theirs works and yours doesn't.

Exetra
24th December 2012, 19:49
dllmain.cpp :

#include <Windows.h>
#include <QApplication>
#include "AppThread.h"

BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
DisableThreadLibraryCalls(hModule);
AppThread * thread = new AppThread();
thread->start();
}

return TRUE;
}


AppThread.h:


#ifndef APPTHREAD_H
#define APPTHREAD_H
#include <QThread>
#include <QApplication>
#include <QMessageBox>
#include "TestUI.h"

class AppThread : public QThread
{
int result;
void run()
{
int a = 0;
QApplication myQapp(a, NULL);
TestUI w;
w.show();
result = myQapp.exec();
}
public:
AppThread() {}
};

#endif // APPTHREAD_H

wysota
25th December 2012, 10:08
I don't think it matters that much but try passing correct arguments to QApplication constructor (you should pass at least the executable name). It can also matter that you are using Qt 5. It can also matter what your TestUI contains. It can also matter what the rest of your code does (especially if it interoperates with the UI somehow).