0

原帖

我有一个 Qt 应用程序。此应用程序需要调用隐式加载的动态库中的某些函数。在动态库中,有一个全局变量,在加载dll时创建,在卸载时销毁。

这是代码:

#include <QApplication>

#include <base/BASE_TEST.h>

int main(int qargc, char** qargv)
{
  QApplication application(qargc, qargv);

  BASE_TEST::myDLLFunction(); // call to a function in an implicitly loaded dynamic library.

  return 0;
}

myDLLFunction 和全局对象的私有类的实现。

#include <base/BASE_TEST.h>

#include <stdio.h>

class MyTest
{
public:
  MyTest() { printf("------------------------------\nTEST BEGIN\n------------------------------\n"); }
  ~MyTest() { printf("------------------------------\nTEST END\n------------------------------\n"); }
};

MyTest test; // created at the library's loading

void BASE_TEST::myDLLFunction()
{
  printf("Call from dynamic library\n");
}

如果我运行应用程序,以下是命令提示符中打印的内容:

------------------------------
TEST BEGIN
------------------------------
Call from dynamic library
------------------------------
TEST END
------------------------------

到这里为止一切都很好。但是,如果我使用 QApplication::desktop() 检索有关屏幕数量的一些信息,动态库的全局对象不会被破坏。

int main(int qargc, char** qargv)
{
  QApplication application(qargc, qargv);
  QDesktopWidget* desktop = QApplication::desktop(); // This call prevent the global objects to be destroyed.

  BASE_TEST::myDLLFunction(); // call to a function in an implicitly loaded dynamic library.

  return 0;
}

以下是命令提示符中打印的内容:

------------------------------
TEST BEGIN
------------------------------
Call from dynamic library

main 函数仍然正常返回,没有抛出异常。

我查看了 QApplication 和 QDesktopWidget 的代码,并且 QDesktopWidget 析构函数在主函数范围的末尾被调用,并且 QDesktopWidgetPrivate::cleanup() 被调用。

我在 Windows 上,使用 Qt 4.8.6。

有人有什么想法吗?谢谢!:)

编辑

正如下面的答案中提到的,问题似乎与加载 wintab32.dll 有关,如果安装,它将加载 Wacom 驱动程序的动态库。

4

1 回答 1

1

我终于找到了问题的根源:

调用 QApplication::desktop() 会加载 Wacom_Tablet.dll。通过卸载 Wacom 驱动程序,问题就消失了。

我能够将示例程序简化为:


#include "../baseTest/BASE_TEST.h"

#include <wtypes.h>
#include "wintab.h"

typedef UINT(WINAPI *PtrWTInfo)(UINT, UINT, LPVOID);

static PtrWTInfo ptrWTInfo = 0;

int main(int /*qargc*/, char** /*qargv*/)
{
  BASE_TEST::myDLLFunction(); // call to a function in an implicitly loaded dynamic library.

  HMODULE hWintab = LoadLibrary(L"wintab32.dll");

  PtrWTInfo pWTInfo = (PtrWTInfo)GetProcAddress(hWintab, "WTInfoW");

  WORD thisVersion;
  pWTInfo(WTI_INTERFACE, IFC_SPECVERSION, &thisVersion);

  if (hWintab)
    FreeLibrary(hWintab);

  return 0;
}

并且仍然能够重现该问题。

我已经联系了 Wacom,正在等待他们的回复。

于 2020-07-23T20:19:07.333 回答