外部库的创建见我上篇文章:Qt使用MinGw和MSVC两种方法生成静态库和动态库
MinGw
使用动态库
第一步:新建项目
第二步:编译器选择mingw
第三步:右键任意文件,在explorer中打开,新建两个文件夹,bin和include
bin文件夹:存放最后编译的工程app可执行文件、以及动态链接库
include文件夹:存放第三方库依赖的头文件
第四步:将动态库文件分别放到bin和include文件夹中
bin文件夹
include文件夹
第五步:右键项目,添加库
第六步:选择外部库
这个勾不勾无所谓,还是不勾了
剩下的下一步然后确定就行,然后就可以看到pro文件中多了
第七步:编写代码,测试能否使用
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include "firstdll.h"QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private:Ui::MainWindow *ui;FirstDll* m_firstDll;//在C和C++中,当你想要调用动态库(或共享库)中的函数时,你需要知道该函数的签名(即它的返回类型和参数类型)。//但是,由于动态库在编译时并不直接链接到你的程序中,你不能像调用普通函数那样直接调用库中的函数。//相反,你需要通过某种方式获取该函数在内存中的地址,然后通过这个地址来调用它。//typedef int (*add)(int,int); 这行代码定义了一个函数指针类型,它指向一个接受两个int参数并返回int的函数。//这种类型定义允许你声明一个这种类型的变量(例如add f_add;),然后用它来存储从动态库中获取的函数的地址。//一旦你有了这个地址,你就可以通过解引用函数指针来调用该函数,就像调用普通函数一样,但是你需要使用函数指针作为调用者。//即typedef 函数返回值类型 (*函数名)(函数参数类型);//函数名 自定义函数名;typedef int (*sub)(int,int);sub f_sub;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QLibrary>
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);m_firstDll = new FirstDll;//使用动态库的成员函数qDebug()<<m_firstDll->add(3,5);qDebug()<<m_firstDll->isFalse;m_firstDll->print();//使用类外函数QLibrary mydll("FirstDll");//mydll.resolve("sub")返回的是一个void*类型的指针,它指向“add”函数的地址。//通过强制类型转换((sub)),我们将这个void*指针转换为适当的函数指针类型f_sub = (sub)mydll.resolve("sub");//即 自定义函数名 = (函数名)mylib.resolve("dll中的函数名"qDebug()<<"相减输出为:"<<f_sub(5,4);
}MainWindow::~MainWindow()
{delete ui;delete m_firstDll;
}
输出结果为
完成
使用静态库
第一步:新建项目
第二步:编译器选择mingw
第三步:右键任意文件,在explorer中打开,新建两个文件夹,lib和include
lib文件夹用于放静态库文件
第四步:将静态库文件分别放到lib和include文件夹中
lib文件夹
include文件夹
第五步:右键项目,添加库,选择外部库
然后下一步,确定,即添加完成,可以看下pro文件多了
第六步:编写代码,测试能否使用
Widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include "firstlib.h"class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
private:FirstLib* m_firstLib;
};
#endif // WIDGET_H
Widget.cpp
#include "widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent): QWidget(parent)
{m_firstLib = new FirstLib;qDebug()<<"相加为:"<<m_firstLib->add(3,2);m_firstLib->print();
}Widget::~Widget()
{delete m_firstLib;
}
完成
MSVC
使用动态库
第一步:新建项目
第二步:编译器选择msvc
第三步:右键任意文件,在explorer中打开,新建两个文件夹,bin和include
bin文件夹:存放最后编译的工程app可执行文件、以及动态链接库
include文件夹:存放第三方库依赖的头文件
第四步:将动态库文件分别放到bin和include文件夹中
bin文件夹
include文件夹
第五步:右键项目,添加库
第六步:选择外部库
可以看到pro文件中多了
第七步:编写代码,测试能否使用
useDll.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include "secondDll.h"class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
public:SecondDll* m_secondDll;//在C和C++中,当你想要调用动态库(或共享库)中的函数时,你需要知道该函数的签名(即它的返回类型和参数类型)。//但是,由于动态库在编译时并不直接链接到你的程序中,你不能像调用普通函数那样直接调用库中的函数。//相反,你需要通过某种方式获取该函数在内存中的地址,然后通过这个地址来调用它。//typedef int (*add)(int,int); 这行代码定义了一个函数指针类型,它指向一个接受两个int参数并返回int的函数。//这种类型定义允许你声明一个这种类型的变量(例如add f_add;),然后用它来存储从动态库中获取的函数的地址。//一旦你有了这个地址,你就可以通过解引用函数指针来调用该函数,就像调用普通函数一样,但是你需要使用函数指针作为调用者。//即typedef 函数返回值类型 (*函数名)(函数参数类型);//函数名 自定义函数名;typedef int (*sub)(int,int);sub f_sub;
};
#endif // WIDGET_H
useDll.cpp
#include "widget.h"
#include <QDebug>
#include <QLibrary>Widget::Widget(QWidget *parent): QWidget(parent)
{//使用动态库的成员函数m_secondDll = new SecondDll;qDebug()<<m_secondDll->add(2,3);qDebug()<<m_secondDll->isFalse;m_secondDll->print();//使用类外函数QLibrary mydll("SecondDll");f_sub = (sub)mydll.resolve("sub");qDebug()<<"相减为:"<<f_sub(2,3);
}Widget::~Widget()
{delete m_secondDll;
}
编译并运行
完成
使用静态库
第一步:新建项目
第二步:编译器选择msvc
第三步:右键任意文件,在explorer中打开,新建两个文件夹,lib和include
第四步:将静态库文件分别放到lib和include文件夹中
lib文件夹
include文件夹
第五步:右键项目,添加库
第六步:选择外部库
可以看到pro文件中多了
第七步:编写代码,测试能否使用
useLib.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include "secondlib.h"class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
public:SecondLib* m_secondLib;
};
#endif // WIDGET_H
useLib.cpp
#include "widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent): QWidget(parent)
{m_secondLib = new SecondLib;qDebug()<<m_secondLib->add(3,9);m_secondLib->print();
}Widget::~Widget()
{delete m_secondLib;
}
编译运行
这里编译我遇到一个问题
SecondLib.lib(secondlib.obj):-1: error: LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“0”不匹配值“2”(main.obj 中)
意思是我用的是release编译的库,但是我本项目(uselib)编译时采用的时debug,这时改下项目的编译方式为release就行了