Qt - Dialog in a DLL

1.6k views Asked by At

In my company, we are developing with Embarcadero-C++-IDE (which is very uncomfortable). To start moving away, we port individual dialogs in a dll to Qt. My qt-dll-code Looks like this for example

extern "C" ROBOTECHPOLYLINEDIALOGSHARED_EXPORT void popupRoboTechDialog()
{
    if( ! QApplication::instance() )
    {
    int argc = 1;
    char *argv[] = {"Design polyline"};
    QApplication app(argc, argv);
    RoboTechPolyline dialog;
    dialog.show();
    app.exec();
    }
    else
    {
    RoboTechPolyline Dialog;
    Dialog.exec(); 
    }  
}

Trying to start the Dialog from another thread like here Starting Qt GUI from dll (in DLLStart function) did make my Dialog unresponsive, but I don't think the question and mine relate too much.

I'm loading this Dll dynamically from the main-application and it works fine. However, when I make the Dialog Pop up a second time I get an "Access Violation at address .. in module MSVCR110D.dll" and on the third time, I get "ASSERT failure in QCoreApplication , there should be only one application object". So I always Need to Close the whole application in order to make the Dialog appear a second time, which greaty slows down work. If I add at the bottom the line

QApplication::quit()

the Dialog appears a second time, but the Programm crashes on closing this second Dialog. The code to load the dll is as follows

HINSTANCE lib = ::LoadLibrary(L"RoboTechPolylineDialog.dll");
if(!lib)
{
    ShowMessage("Unable to load RoboTechPolylineDialog.dll");
    return;
}

typedef void ( *POPUP_ROBO_TECH_DIALOG )();
POPUP_ROBO_TECH_DIALOG fp = (POPUP_ROBO_TECH_DIALOG) ::GetProcAddress(lib, "popupRoboTechDialog"); 

if(!fp)
{
    ShowMessage("Unable to load function popupRoboTechDialog from RoboTechPolylineDialog.dll");
    ::FreeLibrary(lib);
    return;
}

(*fp)( );

FreeLibrary(lib);

So why am I constructing more than one QApplication at a time? I can in above code replace the line

(*fp)();

with

(*fp)();
(*fp)();

and the Dialog appears twice and everything works greatly. But how can the call to ::FreeLibrary(lib) make things fail.

Can anyone help me? Any help, Workarounds, etc.. is appreciated.

2

There are 2 answers

3
Frank Escobar On

Another advice: load Qt libs from as subpath since you could find dll conflict with other apps using it on the same folder (personal experience)

0
fassl On

This should work:

#include <QApplication>
#include <QString>
#include <QDialog>

class App {
    QApplication *_app;
public:
    App(int argc = 0, char** argv = NULL)
        : _app(new QApplication(argc, argv))
    {

    }

    ~App() {
        delete _app;
    }
};

void dialog()
{
    static int argc = 1;
    static char *argv[] = {"Design polyline"};
    static App(argc, argv);
    QDialog dlg;
    dlg.exec();
}

void main()
{
    dialog();
    dialog();
    dialog();
}