http://blog.youkuaiyun.com/zhuce0001/article/details/20651025
本文主要讲解在QT开发环境中如何使用VC生成的DLL及QT自身生成的DLL。至于其它情况本文不作讨论。
连接库分为2种
(1)动态连接库,通常有.h .lib .dll三个文件,功能实现在dll中
(2)静态连接库,通常有.h .lib二个文件,功能实现在lib中
由上可以看出动态库的lib和静态库的lib文件是不同的。
如果使用生成连接库的开发环境与使用连接库的开发环境相同,一般不会出什么问题,如VC写的连接库
(包括动态库和静态库)还在VC中用一般不会有什么问题的。有时候我们需要DLL跨开发环境,如以前VC下的
DLL想在QT中用。有网友说QT不支持VC生成的静态库,所以只测试QT使用动态库的情况。
【先看VC生成的DLL】
使用VC6建立Win32 dynamic-link library工程,工程中只有两个文件,编译即可生成DLL和LIB
- // MFCDLL.h /
- #ifndef _MFCDLL_H
- #define _MFCDLL_H
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- #ifdef DLL
- // do nothing
- #else
- #define DLL __declspec(dllimport)
- #endif
-
- DLL void hello();
- DLL int add(int a, int b);
-
- #ifdef __cplusplus
- }
- #endif
-
- #endif
-
- #define DLL __declspec(dllexport)
- #include "MFCDLL.h"
- #include <windows.h>
-
- void hello()
- {
- ::MessageBox(NULL, "hello world!",
- "greeting", MB_OK);
- }
-
- int add(int a, int b)
- {
- return a + b;
- }
【使用QT生成DLL】使用QT建立动态库工程,编译即可得到DLL(无LIB文件)
-
- #ifndef QTDLL_GLOBAL_H
- #define QTDLL_GLOBAL_H
-
- #include
-
- #if defined(QTDLL_LIBRARY)
- # define QTDLLSHARED_EXPORT Q_DECL_EXPORT
- #else
- # define QTDLLSHARED_EXPORT Q_DECL_IMPORT
- #endif
-
- #endif // QTDLL_GLOBAL_H
-
- #ifndef QTDLL_H
- #define QTDLL_H
-
- #include "qtdll_global.h"
-
- class QTDLLSHARED_EXPORT QTDLL
- {
- public:
- QTDLL();
-
- public:
- int add(int a, int b);
- };
-
- #endif // QTDLL_H
-
- #include "qtdll.h"
-
-
- QTDLL::QTDLL()
- {
- }
-
- int QTDLL::add(int a, int b)
- {
- return a + b;
- }
【QT显式加载VC生成的DLL】
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- #include <QLibrary>
- #include <QDebug>
-
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
-
-
-
- typedef void(*FUN1)();
- typedef int(*FUN2)(int, int);
-
- QLibrary lib("MFCDLL.dll");
- if (lib.load()) {
- qDebug() << "load ok!";
-
- FUN1 hello = (FUN1)lib.resolve("hello");
- FUN2 add = (FUN2)lib.resolve("add");
- if (hello) {
- qDebug() << "load hello ok!";
- hello();
- }
- if (add) {
- qDebug() << "load add ok!";
- qDebug() << add(3, 5);
- }
- } else {
- qDebug() << "load error!";
- }
- }
【QT隐式加载VC生成的DLL】
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- #include "lib/MFCDLL.h"
- #include <QDebug>
-
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
-
-
-
-
-
- hello();
- qDebug() << add(5, 6);
- qDebug() << "ok";
- }
pro工程文件中要设置LIB文件路径
- # lib文件路径
- LIBS += "F:/lib/MFC_DLL_TEST_WITH_QT_2/lib/MFCDLL.lib"
【QT使用QT生成的动态库,隐式】
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- #include <QDebug>
- #include "lib/qtdll.h"
-
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
-
-
-
-
-
- QTDLL dll;
- qDebug() << dll.add(3, 5);
- }
pro工程文件中的设置
-
- LIBS += "F:/lib/QT_DLL_TEST_WITH_DLL/lib/QTDLL.dll"
http://www.cnblogs.com/hicjiajia/archive/2010/08/27/1810239.html
声明: 事先我已经自己动手写了一个简单的dll文件(myDLL.dll),C版接口的。并且用我前两篇有关DLL文章里面的方法,从dll中导出了导入库(.lib)文件,dll中有两个函数,原型如下:
void HelloWorld();
//函数内部调用Win32 API,功能是弹出一个helloworld提示框
int add(
int a,
int b);
//实现两个数相加,并返回结果
下面分别通过显示调用和隐式调用两种方法,来模拟Qt如何调用外部dll文件中的功能函数,follow me....
预备知识:
1、如果在没有导入库文件(.lib),而只有头文件(.h)与动态链接库(.dll)时,我们才需要显示调用,如果这三个文件都全的话,我们就可以使用简单方便的隐式调用。
2、通常Windows下程序显示调用dll的步骤分为三步(三个函数):LoadLibrary()、GetProcAdress()、FreeLibrary()
其中,LoadLibrary() 函数用来载入指定的dll文件,加载到调用程序的内存中(DLL没有自己的内存!)
GetProcAddress() 函数检索指定的动态链接库(DLL)中的输出库函数地址,以备调用
FreeLibrary() 释放dll所占空间
1、显示调用
Qt提供了一个 QLibrary 类供显示调用。下面给出一个完整的例子:
1 #include <QApplication>
2 #include <QLibrary>
3 #include <QDebug>
4 #include <QMessageBox>
5 #include
"
dll.h
"
//引入头文件
6 typedef
int (*Fun)(
int,
int);
//定义函数指针,以备调用
7
int main(
int argc,
char **argv)
8 {
9 QApplication app(argc,argv);
10 QLibrary mylib(
"
myDLL.dll
");
//声明所用到的dll文件
11
int result;
12
if (mylib.load())
//判断是否正确加载
13 {
14 QMessageBox::information(NULL,
"
OK
",
"
DLL load is OK!
");
15 Fun open=(Fun)mylib.resolve(
"
add
");
//援引 add() 函数
16
if (open)
//是否成功连接上 add() 函数
17 {
18 QMessageBox::information(NULL,
"
OK
",
"
Link to Function is OK!
");
19 result=open(
5,
6);
//这里函数指针调用dll中的 add() 函数
20 qDebug()<<result;
21 }
22
else
23 QMessageBox::information(NULL,
"
NO
",
"
Linke to Function is not OK!!!!
");
24 }
25
else
26 QMessageBox::information(NULL,
"
NO
",
"
DLL is not loaded!
");
27 return 0; //加载失败则退出
28}
myDLL.dll为自定义的dll文件,将其复制到程序的输出目录下就可以调用。显然,显示调用代码书写量巨大,实在不方便。
2、隐式调用
这个时候我们需要三个文件,头文件(.h)、导入库文件(.lib)、动态链接库(.dll),具体步骤如下:
1、首先我们把 .h 与 .lib/.a 文件复制到程序当前目录下,然后再把dll文件复制到程序的输出目录,
2、下面我们在pro文件中,添加 .lib 文件的位置: LIBS+= -L D:/hitempt/api/ -l myDLL
-L 参数指定 .lib/.a 文件的位置
-l 参数指定导入库文件名(不要加扩展名)
另外,导入库文件的路径中,反斜杠用的是向右倾斜的
3、在程序中include头文件(我试验用的dll是用C写的,因此要用 extern "C" { #include "dll.h" } )
下面是隐式调用的实例代码:
1 #include <QApplication>
2 #include <QDebug>
3
extern
"
C
"
//由于是C版的dll文件,在C++中引入其头文件要加extern "C" {},注意
4 {
5 #include
"
dll.h
"
6 }
7
int main(
int argv ,
char **argv)
8 {
9 QApplication app(argv,argv);
10 HelloWordl();
//
调用Win32 API 弹出helloworld对话框
11 qDebug()<<add(
5,
6);
//
dll 中我自己写的一个加法函数
12
return 0;
//完成使命后,直接退出,不让它进入事件循环
13 }
还是隐式调用方便啊,直接就可以调用dll中的函数...