qt linux 导出类,QT中dll的生成及使用

C++中的库分为三种:静态库、动态库和导入库

1、静态库:

静态库扩展名为.lib,静态链接(即代码会直接编译进可执行文件)。静态库是一个或多个obj文件的打包。

2、动态库和导入库

和静态库不同,动态库不会编译进可执行文件中,多个程序引用动态库时,内存中实际只会有一份动态库的内容。

用QT创建动态库时,实际生成两个文件,一个lib文件和一个dll文件,这个lib文件就是导入库。

导入库是动态库的辅助库,导入库中不含代码,而是为链接程序提供信息,包含在.exe文件中建立动态链接时要用到的重定位表。

导入库用于程序开发时,动态库用于程序运行时。

3、在项目中使用动态库的方法

1) 隐式加载

这种方式和静态库的使用方法一样,注意此时要包含的是导入库而不是动态库,依然需要头文件,代码中可直接使用头文件中的函数名,并且这种方式在运行时需要动态库。

2) 显式加载(又称运行时动态链接):

如果使用windows接口,则在代码中使用LoadLibrary()显式打开dll文件,使用GetProcAddress获取函数地址然后使用,使用完之后用FreeLibrary显式释放dll文件。这种方式不需要导入库及.h文件。

在QT中则可以使用QLibrary的load方法。

注:使用隐式加载时,如果进程在启动时未找到dll,则操作系统将终止此进程。但使用显式加载时则进程不会被终止。

以上参考:https://blog.csdn.net/finewind/article/details/44959039

https://www.jianshu.com/p/8743a0edb1ee

4、隐示加载dll demo

创建一个TestDll项目,创建项目的时候选择 Library->C++库

2851c0f7f4a9

image.png

pro文件

QT -= gui

TARGET = TestDll

TEMPLATE = lib

DEFINES += TESTDLL_LIBRARY

SOURCES += testDll.cpp

HEADERS += testdll.h\

testdll_global.h \

basetest.h

unix {

target.path = /usr/lib

INSTALLS += target

}

testDll.h

#ifndef TESTDLL_H

#define TESTDLL_H

#include "basetest.h"

#include "testdll_global.h"

class TESTDLLSHARED_EXPORT TestDll : public BaseTest

{

public:

TestDll();

virtual int add(int a, int b);

};

extern "C" {

TESTDLLSHARED_EXPORT BaseTest *getObj();

}

#endif // TESTDLL_H

basetest.h

#ifndef BASETEST

#define BASETEST

class BaseTest

{

public:

BaseTest() {}

virtual int add(int a, int b) = 0;

};

#endif // BASETEST

testdll_global.h

#ifndef TESTDLL_GLOBAL_H

#define TESTDLL_GLOBAL_H

#include

#if defined(TESTDLL_LIBRARY)

# define TESTDLLSHARED_EXPORT Q_DECL_EXPORT

#else

# define TESTDLLSHARED_EXPORT Q_DECL_IMPORT

#endif

#endif // TESTDLL_GLOBAL_H

testDll.cpp

#include "testdll.h"

TestDll::TestDll()

{

}

int TestDll::add(int a, int b)

{

return a + b;

}

BaseTest *getObj()

{

return new TestDll();

}

构建之后会在build同时生成一个.lib和.dll文件

2851c0f7f4a9

image.png

TestDll.lib即为导出库

创建一个DllUser项目

QT += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = DllUser

TEMPLATE = app

SOURCES += main.cpp\

mainwindow.cpp

INCLUDEPATH += include

HEADERS += mainwindow.h

FORMS += mainwindow.ui

LIBS += lib/TestDll.lib

CONFIG(debug, debug|release){

DESTDIR = bin/Debug

} else {

DESTDIR = bin/Debug

}

在该工程的根目录下创建一个lib文件夹,将dll的导出库拷贝到该目录

在根目录下创建一个include文件夹,将dll的头文件拷贝到该目录

并将TestDll.dll拷贝至DllUser.exe的同级目录

2851c0f7f4a9

image.png

mainwindow.cpp代码:

#include "mainwindow.h"

#include "ui_mainwindow.h"

#include "include/testdll.h"

MainWindow::MainWindow(QWidget *parent) :

QMainWindow(parent),

ui(new Ui::MainWindow)

{

ui->setupUi(this);

}

MainWindow::~MainWindow()

{

delete ui;

}

void MainWindow::on_pushButton_clicked()

{

int a = ui->lineEdit->text().toInt();

int b = ui->lineEdit_2->text().toInt();

TestDll obj;

int sum = obj.add(a, b);

QString str = QString::number(sum);

ui->label->setText(str);

ui->label->show();

}

5、显示加载dll demo

显示加载如果只是导出一个函数比较简单,但是如果要导出一个类的话稍微有些麻烦,该demo主要演示如何从dll中导出一个类。

首先,定义一个BaseTest抽象类作为TestDll的基类,BaseTest的头文件需要在使用Dll的项目中引用

DLL的项目代码在4中已展示

下面创建一个显示加载该dll的项目DllLoad, pro文件如下:

QT += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = DllLoad

TEMPLATE = app

INCLUDEPATH += include

SOURCES += main.cpp\

mainwindow.cpp

HEADERS += mainwindow.h

FORMS += mainwindow.ui

CONFIG(debug, debug|release){

DESTDIR = bin/Debug

} else {

DESTDIR = bin/Debug

}

注意需要在该项目的根目录下创建include目录,并将抽象类BaseTest的头文件basetest.h拷贝到该文件夹下,DllLoad不需要再引用dll的其他头文件

mainwindow.cpp的代码

#include

#include

#include

#include "mainwindow.h"

#include "ui_mainwindow.h"

#include "include/basetest.h"

typedef BaseTest* (*Get_Obj)(); //定义函数指针,以备调用

BaseTest *g_obj = NULL;

MainWindow::MainWindow(QWidget *parent) :

QMainWindow(parent),

ui(new Ui::MainWindow)

{

ui->setupUi(this);

loadDll();

}

MainWindow::~MainWindow()

{

delete ui;

}

void MainWindow::loadDll()

{

QLibrary testLib("TestDll.dll");

if (testLib.load()) {

Get_Obj getObj = (Get_Obj)testLib.resolve("getObj");

if (getObj) {

qDebug()<

g_obj = getObj();

}

}

}

void MainWindow::on_pushButton_clicked()

{

int a = ui->lineEdit->text().toInt();

int b = ui->lineEdit_2->text().toInt();

if (g_obj) {

int sum = g_obj->add(a, b);

QString str = QString::number(sum);

ui->label->setText(str);

ui->label->show();

}

}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值