Qt中创建使用动态链接库详解及实例

目录

1、建立并生成动态链接库

2、测试生成的DLL

验证环境:ubuntu18.04+Qt5.14

验证内容:导出类,导出函数带参数/不带参数的函数。

1、建立并生成动态链接库
1、打开QtCreator,新建工程,我们选择Library,C++库,然后就是choose。

2、然后在弹出的C++库对话框我们默认类型共享库,名称为MyDll。然后,一直下一步,直到点击完成。

3、生成的代码结构

MyDll.pro

QT -= gui # 不需要界面

TARGET = MyDll #工程名
TEMPLATE = lib # 生成lib

DEFINES += MYDLL_LIBRARY # 预定义宏
DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += \
mydll.cpp

HEADERS += \
mydll.h \
mydll_global.h

unix {
target.path = /usr/lib
INSTALLS += target
}

mydll_global.h中,内容如下:

#ifndef MYDLL_GLOBAL_H
#define MYDLL_GLOBAL_H

#include <QtCore/qglobal.h>

#if defined(MYDLL_LIBRARY)
# define MYDLLSHARED_EXPORT Q_DECL_EXPORT
#else
# define MYDLLSHARED_EXPORT Q_DECL_IMPORT
#endif

#endif // MYDLL_GLOBAL_H
可以看到系统自动定义了两个宏。用于声明哪些函数是需要我们导出的。

4、导出类,导出函数

首先我们在mydll.h中添加几行代码,如下图。注意:extern "C" MYDLLSHARED_EXPORT必须要有。

#ifndef MYDLL_H
#define MYDLL_H
#include mydll_global.h

class MYDLLSHARED_EXPORT MyDll
{
public:
MyDll();
virtual int sub(int a, int b);
};

extern C MYDLLSHARED_EXPORT void sayHello(); # 导出无参函数
extern C MYDLLSHARED_EXPORT int add(int a, int b); # 导出带参函数

extern C MYDLLSHARED_EXPORT MyDll *getMyDll(); # 导出类接口
#endif // MYDLL_H

mydll.cpp中的实现代码如下:

#include mydll.h
#include <iostream>

MyDll::MyDll()
{
}

int MyDll::sub(int a, int b)
{
return a-b;
}

void sayHello()
{
std::cout<<hello!<<std::endl;
}

int add(int a, int b)
{
return a+b;
}

MyDll * getMyDll()
{
return new MyDll();
}

代码编写完毕后,我们直接构建就行了。然后就可以看到我们生成的动态库了。

2、测试生成的DLL
1、新建一个基于Qt的控制台应用程序,名称为DllTest,与MyDll放在同一级目录下。

2、建好了以后,就可以进行调用验证了。

调用编译好的动态库需要引用两个东西:动态库的头文件和动态库文件。

1)在.pro中添加对Lib的引用

LIBS += ../build-MyDll-unknown-Release/mydll.o
2)在引用文件中,添加头文件的引用

#include ../MyDll/mydll.h
main.cpp调用完整代码:

#include <QCoreApplication>
#include <QLibrary>
#include <iostream>
#include ../MyDll/mydll.h

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

sayHello();
int c = add(1, 2);
std::cout<<add(1,2) = << c << std::endl;
MyDll *mydll = getMyDll();
int d = mydll->sub(2,1);
std::cout<<mydll->sub(2,1) = << d << std::endl;

return a.exec();
}

输出结果:

/********************************************************

QT开发——动态链接库创建

一、创建动态链接库项目


二、删除global文件,修改代码
#ifndef QTLIB_H
#define QTLIB_H

#include <QtGlobal>

// 导出类
class Q_DECL_EXPORT QtLib
{
public:

    QtLib();
};

//导出函数
extern "C" Q_DECL_EXPORT void LibFunc();
#endif // QTLIB_H


#include "qtlib.h"
#include<QDebug>

QtLib::QtLib()
{
   qDebug()<<"LibClass";

}


void LibFunc()
{
    qDebug()<<"LibFunc";
}


三、编译后,找到下面几个文件,放到新的项目文件目录下


四、确保新项目不是影子创建


五、在新项目pro文件下添加代码
LIBS += -L. -lqtlib
1
之后即可调用库中的函数

#include <qtlib.h>
LibFunc();
QtLib lib;
/**********************************************************

qt使用动态库(DLL)

本文主要讲解在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
 

 
 
  1. // MFCDLL.h /

  2. #ifndef _MFCDLL_H

  3. #define _MFCDLL_H

  4. #ifdef __cplusplus

  5. extern "C" {

  6. #endif

  7. #ifdef DLL

  8. // do nothing

  9. #else

  10. #define DLL __declspec(dllimport)

  11. #endif

  12. DLL void hello();

  13. DLL int add(int a, int b);

  14. #ifdef __cplusplus

  15. }

  16. #endif

  17. #endif

 
 
  1. // MFCDLL.cpp /

  2. #define DLL __declspec(dllexport)

  3. #include "MFCDLL.h"

  4. #include <windows.h>

  5. void hello()

  6. {

  7. ::MessageBox(NULL, "hello world!",

  8. "greeting", MB_OK);

  9. }

  10. int add(int a, int b)

  11. {

  12. return a + b;

  13. }

【使用QT生成DLL】 使用QT建立动态库工程,编译即可得到DLL(无LIB文件)

 
 
  1. // qtdll_global.h //

  2. #ifndef QTDLL_GLOBAL_H

  3. #define QTDLL_GLOBAL_H

  4. #include

  5. #if defined(QTDLL_LIBRARY)

  6. # define QTDLLSHARED_EXPORT Q_DECL_EXPORT

  7. #else

  8. # define QTDLLSHARED_EXPORT Q_DECL_IMPORT

  9. #endif

  10. #endif // QTDLL_GLOBAL_H

 
 
  1. // qtdll.h /

  2. #ifndef QTDLL_H

  3. #define QTDLL_H

  4. #include "qtdll_global.h"

  5. class QTDLLSHARED_EXPORT QTDLL

  6. {

  7. public:

  8. QTDLL();

  9. public:

  10. int add(int a, int b);

  11. };

  12. #endif // QTDLL_H

 
 
  1. // qtdll.cpp ///

  2. #include "qtdll.h"

  3. QTDLL::QTDLL()

  4. {

  5. }

  6. int QTDLL::add(int a, int b)

  7. {

  8. return a + b;

  9. }

【QT显式加载VC生成的DLL】

 
 
  1. #include "mainwindow.h"

  2. #include "ui_mainwindow.h"

  3. #include <QLibrary>

  4. #include <QDebug>

  5. MainWindow::MainWindow(QWidget *parent) :

  6. QMainWindow(parent),

  7. ui(new Ui::MainWindow)

  8. {

  9. ui->setupUi(this);

  10. // DLL显式加载,只需要DLL文件即可,不需要.H和.LIB文件

  11. // 需要将DLL放到可执行目录中

  12. typedef void(*FUN1)();

  13. typedef int(*FUN2)(int, int);

  14. QLibrary lib("MFCDLL.dll");

  15. if (lib.load()) {

  16. qDebug() << "load ok!";

  17. FUN1 hello = (FUN1)lib.resolve("hello");

  18. FUN2 add = (FUN2)lib.resolve("add");

  19. if (hello) {

  20. qDebug() << "load hello ok!";

  21. hello();

  22. }

  23. if (add) {

  24. qDebug() << "load add ok!";

  25. qDebug() << add(3, 5);

  26. }

  27. } else {

  28. qDebug() << "load error!";

  29. }

  30. }

【QT隐式加载VC生成的DLL】

 
 
  1. #include "mainwindow.h"

  2. #include "ui_mainwindow.h"

  3. #include "lib/MFCDLL.h"

  4. #include <QDebug>

  5. MainWindow::MainWindow(QWidget *parent) :

  6. QMainWindow(parent),

  7. ui(new Ui::MainWindow)

  8. {

  9. ui->setupUi(this);

  10. // DLL隐式加载,只需要.DLL .H和.LIB文件

  11. // 1需要将DLL放到可执行目录中

  12. // 2将LIB路径设置到项目PRO文件中

  13. // 3将头文件包含进来,如果不包含需要自已声明函数原型及来源(本质与包含头文件相同)

  14. hello();

  15. qDebug() << add(5, 6);

  16. qDebug() << "ok";

  17. }

pro工程文件中要设置LIB文件路径

 
 
  1. # lib文件路径

  2. LIBS += "F:/lib/MFC_DLL_TEST_WITH_QT_2/lib/MFCDLL.lib"

【QT使用QT生成的动态库,隐式】

 
 
  1. #include "mainwindow.h"

  2. #include "ui_mainwindow.h"

  3. #include <QDebug>

  4. #include "lib/qtdll.h"

  5. MainWindow::MainWindow(QWidget *parent) :

  6. QMainWindow(parent),

  7. ui(new Ui::MainWindow)

  8. {

  9. ui->setupUi(this);

  10. // QT使用QT生成的DLL

  11. // 1. 包含头文件

  12. // 2. 在工程文件中指定lib路径

  13. // 3. 将动态库拷贝到可执行文件目录

  14. QTDLL dll;

  15. qDebug() << dll.add(3, 5);

  16. }

pro工程文件中的设置

LIBS += "F:/lib/QT_DLL_TEST_WITH_DLL/lib/QTDLL.dll"

猜你喜欢

转载自blog.csdn.net/u011555996/article/details/129092635