Qt中外部库的使用(MinGw与MSVC)

外部库的创建见我上篇文章: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_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    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_OBJECT

public:
    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_OBJECT

public:
    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_OBJECT

public:
    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就行了

完成
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值