• 4326阅读
  • 1回复

[讨论]一个奇怪的问题. 描述在里面. [复制链接]

上一主题 下一主题
离线iamxinbao
 

只看楼主 倒序阅读 楼主  发表于: 2014-04-01
— 本帖被 kimtaikee 从 Qt 作品展 移动到本区(2014-04-01) —
假设有2个项目. 一个是 EXE 一个是DLL
EXE是QT 项目.  EXE隐式Link DLL
如果EXE里面 一个按钮事件:
QFileDialog::getOpenFileName(this);  //运行这个函数
那么DLL 不会卸载.
看下面最小测试代码说明可能直接一点:
DLL 项目:
Out.h
  1. #pragma once
  2. #ifdef EXPORT
  3. #define DLL_API _declspec(dllexport)
  4. #else
  5. #define DLL_API _declspec(dllimport)
  6. #endif // EXPORT
  7. #include <fstream>
  8. class DLL_API ExportVal
  9. {
  10. public:
  11.     ExportVal();
  12.     ~ExportVal();
  13. };
  14. class DLL_API GlobalVarTest
  15. {
  16. public:
  17.     GlobalVarTest()
  18.     {
  19.         mFS.open("Test.txt",std::ios::out);
  20.         mFS.write("123123",sizeof("123123"));
  21.     }
  22.     ~GlobalVarTest()
  23.     {
  24.         mFS.close();
  25.     }
  26.     std::fstream mFS;
  27. };
out.cpp
  1. #include "Out.h"
  2. GlobalVarTest G_Val;
  3. ExportVal::ExportVal()
  4. {
  5. }
  6. ExportVal::~ExportVal()
  7. {
  8. }
  9. #include <windows.h>
  10. BOOL WINAPI DllMain(
  11.   _In_  HINSTANCE hinstDLL,
  12.   _In_  DWORD fdwReason,
  13.   _In_  LPVOID lpvReserved
  14. )
  15. {
  16.     if (fdwReason == DLL_PROCESS_ATTACH)
  17.     {
  18.         //Load lib
  19.         int x = 100;
  20.     }
  21.     if (fdwReason == DLL_PROCESS_DETACH)
  22.     {
  23.         //UnLoad lib
  24.         int x = 100;
  25.     }
  26.     return TRUE;
  27. }

Exe项目:
Test01.h
  1. #ifndef TEST01_H
  2. #define TEST01_H
  3. #include <QtWidgets/QMainWindow>
  4. #include "ui_test01.h"
  5. #include "Out.h"
  6. class Test01 : public QMainWindow
  7. {
  8.     Q_OBJECT
  9. public:
  10.     Test01(QWidget *parent = 0);
  11.     ~Test01();
  12. protected slots:
  13.     void TC();
  14. private:
  15.     Ui::Test01Class ui;
  16. };
  17. #endif // TEST01_H
test01.cpp
  1. #include "test01.h"
  2. #include "QPushButton"
  3. #include "QFileDialog"
  4. Test01::Test01(QWidget *parent)
  5.     : QMainWindow(parent)
  6. {
  7.     ExportVal E = ExportVal();
  8.     QPushButton* But = new QPushButton(this);
  9.     connect(But,&QPushButton::clicked,this,&Test01::TC);
  10. }
  11. Test01::~Test01()
  12. {
  13. }
  14. void Test01::TC()
  15. {
  16.     QFileDialog::getOpenFileName(this);
  17. }

main.cpp
  1. #include "test01.h"
  2. #include <QtWidgets/QApplication>
  3. int main(int argc, char *argv[])
  4. {
  5.     QApplication a(argc, argv);
  6.     Test01 w;
  7.     w.show();
  8.     return a.exec();
  9. }


当你点击按钮后, 你会发现 dll 原来不会被卸载, 但是隐式连接是自动卸载的.!!!
也就是:
  1. if (fdwReason == DLL_PROCESS_DETACH)
  2.     {
  3.         //UnLoad lib 这里从来没被调用过
  4.         int x = 100;
  5.     }

换句话说: dll里面的全局变量没被卸载...!! 析构函数没被调用.
但是如果不点击按钮,然后关闭,那么dll又会正常卸载


真蛋疼, 有谁遇见过这个问题?
我在qt forums 里面也发了一片帖子, 这个问题挺纠结的 比较急 .
这里是连接:
http://qt-project.org/forums/viewthread/40575/
希望大家可以随便新建一个工程 吧上面代码拷贝一下 测试一下.  我测试了很多遍, 结果都是一样.
我的环境是 VS2013  QT5.2.1 WIN8.1 64位




离线iamxinbao

只看该作者 1楼 发表于: 2014-04-01
  真蛋疼 谁有测试一下 不知道是个bug 还是 我环境有问题.?
快速回复
限100 字节
 
上一个 下一个