2015-06-18 14 views
1

В моей компании мы разрабатываем Embarcadero-C++ - IDE (что очень неудобно). Чтобы начать перемещение, мы переносим отдельные диалоги в dll на Qt. Мой кварта-длл-код выглядит как это, напримерQt - Диалог в DLL

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(); 
    } 
} 

Попытка начать диалог из другого потока, как здесь Starting Qt GUI from dll (in DLLStart function) делали мой диалог отвечать на запросы, но я не думаю, что этот вопрос и мое отношения слишком много.

Я загружаю эту Dll динамически из основного приложения и отлично работает. Однако, когда я снова создаю диалог, я получаю «Нарушение доступа по адресу .. в модуле MSVCR110D.dll», и в третий раз я получаю «Сбой ASSERT в QCoreApplication, должен быть только один объект приложения», , Поэтому мне всегда нужно закрыть все приложение, чтобы сделать диалог еще раз, что значительно замедляет работу. Если добавить в нижней части линии

QApplication::quit() 

Диалоговый появляется во второй раз, но Programm сбой при закрытии этого второго диалога. код для загрузки DLL является следующим

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); 

Так почему я построения более одного QApplication в то время? Я могу в коде выше замените строку

(*fp)(); 

с

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

и диалог появляется дважды, и все прекрасно работает. Но как может вызов to :: FreeLibrary (lib) заставляет вещи потерпеть неудачу.

Может ли кто-нибудь мне помочь? Любая помощь, обходные пути и т. Д. Оцениваются.

+1

Вы должны иметь только одно приложение QApplication. Попытайтесь прочитать это http://stackoverflow.com/questions/11054087/starting-qt-gui-from-dll-in-dllstart-function – demonplus

+0

Что я уже прочитал, это мне не помогло. Я не вижу, где у меня более одного QApplication (есть только одна Dll, которая использует Qt, и здесь мне нужно как-то закрыть QApplication.) – mathgenius

+0

Я думаю, проблема в том, что вы вызываете popupRoboTechDialog() несколько раз и QApplication создается несколько раз. Qt предпочитает другой рабочий процесс, поэтому лучше переместить QApplication в другое место – demonplus

ответ

0

Другой совет: загрузить Qt LIBS с, как подпуть, так как вы могли бы найти DLL конфликт с другими приложениями, используя его в той же папке (личный опыт)

+0

Отличный совет. Но как это работает. Я попытался загрузить HINSTANCE lib = :: LoadLibrary (L "QtDlls \ RoboTechPolylineDialog.dll"), и это не сработало. – mathgenius

+0

Я имею в виду загрузку Qt5GUI.dll и т. Д. Из вашего RoboTechPolylineDialog.dll –

+0

Хорошо, и как это будет работать? – mathgenius

2

Это должно работать:

#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(); 
} 
+0

Отлично, это получилось красиво. – mathgenius