DLL 是一个包含可由多个程序同时使用的代码和数据的库, DLL 不是可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。 DLL 还有助于共享数据和资源。多个应用程序可同时访问内存中单个 DLL 副本的内容。 DLL 是一个包含可由多个程序同时使用的代码和数据的库。
因为 QT 必须有调用QApplication的exec方法,这样才能产生消息循环, QT 的程序才可以运行。所以说如果我们使用了 QT 编写了dll程序,在普通的 windows 程序中是不能调用的。在调用的时候会出现错误。当然 QT 提供了解决方法:那就是QTWinmigrate
这里是QT官方网站对QTWinmigrate的介绍:
http://qt.nokia.com/products/appdev/add-on-products/catalog/4/Windows/qtwinmigrate
下面我来介绍一下使用QTWinmigrate来编写dll的方法。
首先,我们要重写DllMain函数:
- #include <qtwinmigrate/qmfcapp.h>
- #include <qtwinmigrate/qwinwidget.h>
- #include <qmessagebox.h>
- #include <windows.h>
- BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpvReserved )
- {
- static bool ownApplication = FALSE;
- if ( dwReason == DLL_PROCESS_ATTACH )
- ownApplication = QMfcApp::pluginInstance( hInstance );
- if ( dwReason == DLL_PROCESS_DETACH && ownApplication )
- delete qApp;
- return TRUE;
- }
大家都知道DllMain函数是 windows 动态库的入口函数,如果在dll中使用了 QT 的ui界面前,全局的QApplication必须首先要创建,并且应用程序必须创建EventLoop。
进入到QmfcApp::pluginInstance方法中去,
- bool QMfcApp::pluginInstance(Qt::HANDLE plugin)
- {
- if (qApp)
- return FALSE;
- QT_WA({
- hhook = SetWindowsHookExW(WH_GETMESSAGE, QtFilterProc, 0, GetCurrentThreadId());
- }, {
- hhook = SetWindowsHookExA(WH_GETMESSAGE, QtFilterProc, 0, GetCurrentThreadId());
- });
- int argc = 0;
- (void)new QApplication(argc, 0);
- if (plugin) {
- char filename[256];
- if (GetModuleFileNameA((HINSTANCE)plugin, filename, 255))
- LoadLibraryA(filename);
- }
- return TRUE;
- }
我们可以看到:Qapplication被创建了出来。QmfcApp::pluginInstanc是为了保证进程中存在一个Qapplication 对象,并且dll要把这个Qapplication的实例加载到内存中。
下面是dll中的导出函数:
dll中的导出函数要用extern “C”形式,QwinWidget为native win32窗口提供堆栈等等。
这样还没有写完程序。不行你拿这个程序来
- qmake -project
- qmake
- nmake
这样是无论如何也编译不过的。
如果你仔细看qtwinmigrate的example的话,你就会注意到:
- include(D:\qt4.4.3\qtwinmigrate-2.8-opensource\src\qtwinmigrate.pri)
编译的时候一定要在*.pro文件中加上。
小结:关于在 QT 实现 Windows 下 DLL 程序编写,内容介绍完了,QApplication这个类还是起来很大的作用。 QT 必须有调用QApplication的exec方法,这样才能产生消息循环, QT 的程序才可以运行。