0

Im trying to implement a DLL which displays a non modal QT window, when you call the exported "OpenUI()" function. The "Access violation reading location ..." occurs when the "OpenUI()" function is called a second time, after closing it the first time. To understand what exactly im doing, please look into the short code below.

Im building the DLL with VS Community 2017 Version 15.9.14, Qt VS Tools 2.3.2 and Qt for MSVC 5.13.0.

For now the window shall show only a QWidgetList with items and a QLabel, both with QVBoxLayout. The QLabel is commented out, because it seems, that it doesnt have any impact on the Exception. When no items are inserted into the QWidgetList, then no Exception will occur (first #if to 0). The second possibility to prevent the Exception is, when i dont use any layout (second #if to 0).


#include <iostream>

#include <Windows.h>

#include <QApplication>
#include <QLabel>
#include <QListWidget>
#include <QVBoxLayout>
#include <QWidget>

using namespace std;
inline void operator<(int, ostream& s) { s << endl; }
#define TO_COUT 17 < cout
#define LOG_I  TO_COUT

#define DLLEXPORT     __declspec(dllexport)
#define C_DLLEXPORT   extern "C" DLLEXPORT

HANDLE hWorker = NULL;
DWORD  dwWorkerId = 0;

DWORD WINAPI WorkerThread(LPVOID lpParam)
{
    LOG_I << "WorkerThread()";

    int argc = 0;
    char *argv[1];
    QApplication app(argc, argv);

    //QLabel* label = new QLabel("Choose:");
    QListWidget* list = new QListWidget;

#if 1
    new QListWidgetItem("a", list);
    new QListWidgetItem("b", list);
    new QListWidgetItem("c", list);
#endif

#if 1
    QVBoxLayout* someLayout = new QVBoxLayout;
    //someLayout->addWidget(label);
    someLayout->addWidget(list);

    QWidget* widget = new QWidget;
    widget->setLayout(someLayout);
    widget->show();
#else
    list->show();
#endif

    int ret = app.exec();
    LOG_I << "ret: " << ret;

    return 0;
}

C_DLLEXPORT UINT32 OpenUI()
{
    LOG_I << "OpenUI()";

    hWorker = CreateThread(NULL, 0, WorkerThread, 0, 0, &dwWorkerId);

    //WaitForSingleObject(hWorker, INFINITE);
    //CloseHandle(hWorker);
    //hWorker = NULL;

    return 0;
}

Question: Is the code missing anything basically?

Luk
  • 1
  • 2
  • 1
    "The non modality is created by constructing a thread and calling "exec()" inside it." - I'm pretty sure Qt requires *all* code that interacts with/concerns GUI elements to run in the main thread. So what you describe sounds like a bad idea. – Jesper Juhl Jul 23 '19 at 16:14
  • @JesperJuhl It doesn't have to be the thread for the `main()` function. All GUI code just needs to be called from the thread that instantiates the `QGuiApplication` object. See https://stackoverflow.com/questions/22289423/how-to-avoid-qt-app-exec-blocking-main-thread/ – JKSH Jul 24 '19 at 03:17
  • @Luk Your general approach is fine; I've done the same: https://github.com/JKSH/LQ-Bindings/blob/master/src/Cpp/lqmain.cpp Try setting `argc = 1` and initialized argv[0] to a valid string. – JKSH Jul 24 '19 at 03:24
  • @ JKSH I tried your proposition, but the Exception still occurs. – Luk Jul 24 '19 at 11:34

0 Answers0