0x00 Qt Creator创建共享库(动态库)项目
// DllSelectSort01_global.h
#ifndef DLLSELECTSORT01_GLOBAL_H
#define DLLSELECTSORT01_GLOBAL_H
#if defined(_MSC_VER) || defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
# define Q_DECL_EXPORT __declspec(dllexport)
# define Q_DECL_IMPORT __declspec(dllimport)
#else
# define Q_DECL_EXPORT __attribute__((visibility("default")))
# define Q_DECL_IMPORT __attribute__((visibility("default")))
#endif
#if defined(DLLSELECTSORT01_LIBRARY)
# define DLLSELECTSORT01_EXPORT Q_DECL_EXPORT
#else
# define DLLSELECTSORT01_EXPORT Q_DECL_IMPORT
#endif
#endif // DLLSELECTSORT01_GLOBAL_H
// dllselectsort01.h
#ifndef DLLSELECTSORT01_H
#define DLLSELECTSORT01_H
#include "DllSelectSort01_global.h"
/*
class DLLSELECTSORT01_EXPORT DllSelectSort01
{
public:
DllSelectSort01();
};
*/
void selectSort(int* arr, int n);
#endif // DLLSELECTSORT01_H
// dllselectsort01.cpp
#include "dllselectsort01.h"
/*
DllSelectSort01::DllSelectSort01()
{
}
*/
void selectSort(int* arr, int n){
for(int i = 0; i < n - 1; i++)
{
for(int j = i + 1; j < n; j++)
{
if(arr[i] > arr[j])
{
arr[i] ^= arr[j];
arr[j] ^= arr[i];
arr[i] ^= arr[j];
}
}
}
}
- 构建动态库时,生成了2个可以加载动态库的文件,一个扩展名为 .a 文件,一个扩展名为 .dll 文件,.a 文件其实是动态库的引导文件
说明:mingw编译器在Windows平台构建动态库时生成的动态库文件为.dll文件,.a文件为动态库的引导文件,可用此文件来加载动态库,这与MSVC编译器不同,MSVC编译器在构建动态库时生成的是.dll文件和.lib文件。
0x01 方式一:隐式调用动态库,即利用构建动态库时生成的静态库文件作为引导去调用动态库
#include <QCoreApplication>
#include "dllselectsort01.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int arr[] = {2020, 10, 9, 1992, 3 ,1994, 4, 16, 520, 6666};
selectSort(arr, sizeof(arr) / sizeof(*arr));
for(int i = 0; i < sizeof(arr) / sizeof(*arr); i++)
{
printf("%d ", arr[i]);
}
return a.exec();
}
- 1. 在CallDll01.pro文件,包含需要引入动态库的头文件路径,以及引导加载动态库的静态库文件所在的路径
- 2. 将动态库.dll文件放到可执行程序所在的目录下
- 1. 显示调用动态库,在建立动态库时,把需要调用的函数或者类需要添加导出修饰语,其构建动态库的方式和隐式调用动态库所构建动态库的方式一样
// DllSelectSort02_global.h
#ifndef DLLSELECTSORT02_GLOBAL_H
#define DLLSELECTSORT02_GLOBAL_H
#if defined(_MSC_VER) || defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
# define Q_DECL_EXPORT __declspec(dllexport)
# define Q_DECL_IMPORT __declspec(dllimport)
#else
# define Q_DECL_EXPORT __attribute__((visibility("default")))
# define Q_DECL_IMPORT __attribute__((visibility("default")))
#endif
#if defined(DLLSELECTSORT02_LIBRARY)
# define DLLSELECTSORT02_EXPORT Q_DECL_EXPORT
#else
# define DLLSELECTSORT02_EXPORT Q_DECL_IMPORT
#endif
#endif // DLLSELECTSORT02_GLOBAL_H
// dllselectsort02.h
#ifndef DLLSELECTSORT02_H
#define DLLSELECTSORT02_H
#include "DllSelectSort02_global.h"
//导出类
class DLLSELECTSORT02_EXPORT DllSelectSort02
{
public:
DllSelectSort02();
};
//导出函数
extern "C" DLLSELECTSORT02_EXPORT void selectSort(int* arr, int n);
#endif // DLLSELECTSORT02_H
// dllselectsort02.cpp
#include "dllselectsort02.h"
DllSelectSort02::DllSelectSort02()
{
}
void selectSort(int* arr, int n){
for(int i = 0; i < n - 1; i++)
{
for(int j = i + 1; j < n; j++)
{
if(arr[i] > arr[j])
{
arr[i] ^= arr[j];
arr[j] ^= arr[i];
arr[i] ^= arr[j];
}
}
}
}
- 2. 显示加载动态库的代码
#include <QCoreApplication>
#include <QLibrary>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//函数指针
typedef void(*selectSortFunc)(int arr[], int n);
QLibrary dll("./DllSelectSort02.dll");
if(dll.load()){
qDebug() << "动态库加载成功!";
}
int arr[] = {2020, 10, 9, 1992, 3 ,1994, 4, 16, 520, 6666};
selectSortFunc selectSort = (selectSortFunc)dll.resolve("selectSort");
if(selectSort){
qDebug() << "函数加载成功!";
selectSort(arr, sizeof(arr) / sizeof(*arr));
}else{
qDebug() << "函数加载失败!!!";
}
for(int i = 0; i < sizeof(arr) / sizeof(*arr); i++){
printf("%d ", arr[i]);
}
return a.exec();
}
- 3. 把动态库放到应用程序所在的目录
0x03 调用静态库
- 1. 构建静态库
// aselectsort.h
#ifndef ASELECTSORT_H
#define ASELECTSORT_H
/*
class ASelectSort
{
public:
ASelectSort();
};
*/
void selectSort(int* arr, int n);
#endif // ASELECTSORT_H
// aselectsort.cpp
#include "aselectsort.h"
/*
ASelectSort::ASelectSort()
{
}
*/
void selectSort(int* arr, int n){
for(int i = 0; i < n - 1; i++)
{
for(int j = i + 1; j < n; j++)
{
if(arr[i] > arr[j])
{
arr[i] ^= arr[j];
arr[j] ^= arr[i];
arr[i] ^= arr[j];
}
}
}
}
- 2. APP调用静态库的工程目录结构
- 3. 在CallA.pro文件,即APP的项目文件中中,引入需要调用静态库所在的路径,以及库的头文件所在的目录
- 4. 代码如下
#include <QCoreApplication>
#include "aselectsort.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int arr[] = {2020, 10, 9, 1992, 3 ,1994, 4, 16, 520, 6666};
selectSort(arr, sizeof(arr) / sizeof(*arr));
for(int i = 0; i < sizeof(arr) / sizeof(*arr); i++)
{
printf("%d ", arr[i]);
}
return a.exec();
}