1、+New Project
2、项目 - Library - c++库 - choose
3、类型 - 共享库
4、名称 - dll1 - 下一步
5、编译器选择 (我是MinGW32)- 下一步
6、选择需要的模块 (我只默认选了 Qt Core)- 下一步
7、类信息(默认就行了)- 下一步
8、项目管理(同上)- 完成
9、生成目录树
dll1
dll1.pro
头文件
dll1.h
dll1_global.h
源文件
dll1.cpp
10、当前文件源码
- dll1.pro
#-------------------------------------------------
#
# Project created by QtCreator 2018-06-26T10:07:39
#
#-------------------------------------------------
QT -= gui
TARGET = dll1
TEMPLATE = lib
DEFINES += DLL1_LIBRARY
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += dll1.cpp
HEADERS += dll1.h\
dll1_global.h
unix {
target.path = /usr/lib
INSTALLS += target
}
#ifndef DLL1_H
#define DLL1_H
#include "dll1_global.h"
class DLL2SHARED_EXPORT Dll1
{
public:
Dll1();
};
#endif // DLL1_H
#ifndef DLL1_GLOBAL_H
#define DLL1_GLOBAL_H
#include
#if defined(DLL1_LIBRARY)
# define DLL1SHARED_EXPORT Q_DECL_EXPORT
#else
# define DLL1SHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // DLL1_GLOBAL_H
#include "dll2.h"
Dll2::Dll2()
{
}
11、关键字介绍
dll1.pro
qmake 的工程(project)文件
dll1.h
主头文件
dll1_global.h
基本概念:符号 - 函数、变量或类 - 包含在供客户端(例如:应用程序或其他库)使用的共享库中,必须以一种特殊的方式标记。这些符号被称为公共符号,它们被导出或公开可见。
使用方法:在编译共享库时,必须将其标记为EXPORT。为了在客户端使用共享库,一些平台可能需要一个特殊的IMPORT声明。
为此,Qt 提供了两个特殊的宏:
- Q_DECL_EXPORT:当编译共享库时,必须将其添加到使用的符号声明。
- Q_DECL_IMPORT:当编译一个(使用了该共享库)客户端时,必须将其添加到使用的符号声明。
结论:
要确保正确的宏能够被调用(无论是编译共享库本身,还是在客户端使用共享库),通常通过添加一个特殊的头文件({projectName}_global.h)来解决,这就是 {projectName}_global.h 存在的原因。
dll1.cpp
源文件
TARGET
指定库的名称
TEMPLATE
模板的意思,将其指定为 lib,是要告诉 qmake 我们需要生成的是一个库文件(app 为可执行程序)。
DEFINES
用于定义编译选项
SOURCES
源文件名字(要包含后缀)
HEADERS
头文件名字(要包含后缀)
INSTALLS
要安装的文件
Q_DECL_EXPORT
导出
Q_DECL_IMPORT
导入
12、当前工程的所有文件改动如下
dll1_global.h
拷贝该文件中的代码 至 头文件dll1.h,然后删除该文件(彻底删除也没关系):
#include
#if defined(DLL1_LIBRARY)
# define DLL1SHARED_EXPORT Q_DECL_EXPORT
#else
# define DLL1SHARED_EXPORT Q_DECL_IMPORT
#endif
dll1.h
在public部分声明函数
void HelloWorld(QString str);
dll1.cpp
添加以下代码
#include
void Dll2::HelloWorld(QString str)
{
qDebug()<;
}
最后,点击构建,即可生成输出。
Note1:在 Windows 中,有动态链接库(DLL - Dynamic Link Library);在 Linux 中,有共享库(Shared Library),它们是相同的!
Note2:由于平台和编译器的差异,输出的库文件也不同:在 Windows 中,MinGW 将输出 .a 和 .dll;MSVC 将输出 .lib 和 .dll。在 Linux 中,MinGW 将输出 .so、.so.1、.so.1.0 和 .so.1.0.0 - .lib;其中.lib .a .so 是导入库,它们有助于将我们的代码链接到库中,并且在构建文件时需要。
Note3: Debug 版本(带 d)为 SharedLibd.lib 和 SharedLibd.dll,Release 版本(不带 d)为 SharedLib.lib 和 SharedLib.dll。
1、+New Project
2、项目 - Application - Qt Console Application - choose
3、名称 - Testdll1 - 下一步
4、编译器选择 (我是MinGW32)- 下一步
5、项目管理(同上)- 完成
6、生成目录树
Testdll1
Testdll1.pro
源文件
main.cpp
7、当前文件源码
Testdll1.pro
QT += core
QT -= gui
CONFIG += c++11
TARGET = Testdll1
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
main.cpp
#include
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
return a.exec();
}
8、导入共享库 dll1 的方法
一、使用Qt Creator提供的方法:
1、编译当前工程,生成debug/release输出文件
2、点击工程
3、右键添加库,选择外部库
4、选择库文件(我选择.a),配置当前对话框信息(我平台选择windows,链接选择动态,Windows选择为debug版本添加"d"作为后缀)
5、拷贝 (dll1D.dll / dll1.dll)至 Testdll1 的Debug路径下(我的是..\build-Testdll1-Desktop_Qt_5_8_0_MinGW_32bit-Debug\debug)
6、在工程添加 dll1.h
7、已经可以在工程中使用 dll1.dll 了,例如在Testdll1.cpp中包含 dll1.h 头文件,再创建dll1的对象或指针,即可通过指针或对象,调用 dll1 的 API 了。
使用方法如下:
#include
#include "dll1.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Dll1 dll;
dll.HelloWorld("HelloWorld");
return a.exec();
}
二、通过 windows 提供的 API 调用
1、编译当前工程,生成debug/release输出文件
2、cpp如下:
#include
int main()
{
//首先定义函数指针,用来接收不同参数的函数
// 第一个关键字 typedef 定义类型模板
// 第二个关键字 可以为其他类型,主要是调用的函数的类型,例如调用int main()就定义int类型的函数指针
// 第三个关键字 CALLBACK 是定义回调函数类型的指针,名字用于后续调用Dll API
// 第四个关键字 是函数的参数,例如 int main()没有参数,则不定义类型,注意只需要声明参数的类型即可,而不需要参数名字
typedef int (CALLBACK *Fucv)();
typedef int (CALLBACK *Fuci)(int);
typedef int (CALLBACK *Fucii)(int,int);
//获得.dll文件的句柄,需要头文件windows.h的支持
HINSTANCE hdll=LoadLibrary(L"Dll1.dll"); //L指宽字符串,若不写L,则会出现错误,详情请自查
//注意这里要用 dll函数查看器 查看到的函数名
Fucv t1=(Fucv)GetProcAddress(hdll,"_Z5test1v");
Fucv t2=(Fucv)GetProcAddress(hdll,"_Z5test2v");
Fuci t3=(Fuci)GetProcAddress(hdll,"_Z5test3i");
Fucii t4=(Fucii)GetProcAddress(hdll,"_Z5test4ii");
//现在的t1就执行的test1的功能,以此类推
t1();
t2();
t3(1);
t4(1,2);
//因为dll本身是没有内存的,上面我们主动分配了,这里用完就要释放dll内存
FreeLibrary(hdll);
}
dll函数查看器
1、还是方法一好用….
后期我有关于 库 的知识更新时,会来更新该博文的