Summary : I have a DLL which exports a function. In this function I am calling QApplication::allWidgets() which returns an empty list whereas if this function is in the application returns a list with 19 items.
If I am not mistaken there is a static list of items maintained by the framework. allWidgets() function is returning that list. To my knowledge DLL is supposed to be in the same address space as the application which means I should be able to access all the static variables from DLL. Then why does it make a difference whether the function is in DLL vs application?
Here is DLL code :
------------------------ test.h ----------------
extern "C" TESTSHARED_EXPORT std::string DllFun();
------------------------ test.cpp --------------
std::string DllFun()
{
std::stringstream temp;
QList<QWidget *> list = QApplication::allWidgets();
temp << "Number of widgets from DLL " << list.size();
return temp.str();
}
Here is the application code snippet :
------------------------------ mainwindow.cpp ----------------
std::string MainWindow::FunInternal()
{
std::stringstream temp;
QList<QWidget *> list = QApplication::allWidgets();
temp << "Number of widgets from Applicaton " << list.size();
return temp.str();
}
void MainWindow::on_pushButton_clicked()
{
typedef std::string (*FunType)();
HMODULE handle = LoadLibrary(L"Test.dll");
FunType DllFun = (FunType)GetProcAddress(handle, "DllFun");
if (Fun)
{
std::string DllWidgets = DllFun();
std::string InternalWidgets = FunInternal();
ui->textEdit->append(QString(DllWidgets.c_str()));
ui->textEdit->append(QString("\n"));
ui->textEdit->append(QString(InternalWidgets.c_str()));
}
}
When I click the button results are :
Number of widgets from DLL 0
Number of widgets from Applicaton 19
I am using Qt 5.2 Mingw 64 Bit.
Update : Here is a workaround that appears to be working even though my question is still valid. If I pass a function pointer to the DLL and call the function pointer from DLL it returns 19 just like application.
As Chris pointed out DLL and Application appears to have two separate Data sections. DLL cannot normally access to the application's data section (which contains state information of the GUI) except through an interface to the data or a pointer to it. In my case this was not possible since my interface is generic. I tried to push this a bit by using GetProcAddress inside my DLL but I did not have much success but I think in theory this should work.
My current design is something like this :
------- genwidget.h
class MyWidget
{
public:
void modifyWidget(HWND id);
}
------- qtwidget.cpp
#include <genwidget.h>
void MyWidget::modifyWidget(HWND id)
{
// find Panel widget
QWidget *widget = find_widget_from_list(id, QApplication::allWidgets())
// do work
}
------- vcwidget.cpp
#include <genwidget.h>
void MyWidget::modifyWidget(HWND id)
{
// find Panel widget
Panel ^widget = find_widget_from_list(id);
// do work
}
I think I have to change my design in the following way to give each environment its own interface.
------- genwidget.h
class MyWidget
{
public:
virtual void modifyWidget() = 0;
}
------- qtwidget.h
class QtMyWidget : public MyWidget
{
public:
QtMyWidget(QWidget *panel);
void modifyWidget();
}
------- vcwidget.h
class VcMyWidget : public MyWidget
{
public:
VcMyWidget(Panel ^panel);
void modifyWidget();
}