Qt创建和调用动态链接库-1

一.创建动态链接库

这里注意是qmake,Qt的新版本会默认CMake

我们的第一种动态库通过C风格的导出文件去封装,这样做的好处是,调用库的时候不需要做太多的库链接设置,如.pro中添加一些内容,也可以提高库的隐蔽性,不对外展示类的结构,只提供调用的口

以下是动态库的代码

.pro

QT -= gui

TARGET = MyDll
DESTDIR = ..\Debug
TEMPLATE = lib
DEFINES += UNTITLED_LIBRARY

CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    ExportDll.cpp \
    untitled.cpp

HEADERS += \
    ExportDll.h \
    untitled_global.h \
    untitled.h

# Default rules for deployment.
unix {
    target.path = /usr/lib
}
!isEmpty(target.path): INSTALLS += target

untitled_global.h

#ifndef UNTITLED_GLOBAL_H
#define UNTITLED_GLOBAL_H

#include <QtCore/qglobal.h>

#if defined(UNTITLED_LIBRARY)
#define UNTITLED_EXPORT Q_DECL_EXPORT
#else
#define UNTITLED_EXPORT Q_DECL_IMPORT
#endif

#endif // UNTITLED_GLOBAL_H

untitled.h

#ifndef UNTITLED_H
#define UNTITLED_H

class Untitled
{
public:
    Untitled();
    void MyActive();
};

#endif // UNTITLED_H

 untitled.cpp

#include "untitled.h"
#include <QDebug>

Untitled::Untitled() {}

void Untitled::MyActive()
{
    qDebug() << "Hello dll";
}

ExportDll.h

#pragma once
#include "untitled_global.h"
#include "untitled.h"

extern "C" UNTITLED_EXPORT void MyActive();

ExportDll.cpp

#include "ExportDll.h"

void MyActive()
{
    Untitled test;
    test.MyActive();
}

二.调用动态链接库

常规创建一个Qt的工程的流程

以下是调用库的代码

.pro

CONFIG += c++17
# 这里直接将exe文件生成在Debug目录下和刚刚动态库一个路径,这样加载库的时候就直接通过相对路径加载
DESTDIR = ..\Debug
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    Demo.cpp

HEADERS += \
    Demo.h

FORMS += \
    Demo.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

Demo.h

#pragma once

#include <QDialog>
#include <QLibrary>

QT_BEGIN_NAMESPACE
namespace Ui {
class CDemo;
}
QT_END_NAMESPACE

class CDemo : public QDialog
{
    Q_OBJECT

public:
    CDemo(QWidget *parent = nullptr);
    ~CDemo();

private:
    bool LoadDll();
    bool Resolve(const QString& sFuncName, QFunctionPointer& pfFunc);
    void MyActive();

private:
    Ui::CDemo *ui;
    QLibrary m_lib;
};

Demo.cpp

#include "Demo.h"
#include "ui_Demo.h"
#include <QDebug>
#pragma execution_character_set("utf-8")

typedef void (*pfMyActive)();

CDemo::CDemo(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::CDemo)
{
    ui->setupUi(this);

    if (m_lib.isLoaded())
        return;

    if (!LoadDll())
        return;

    MyActive();
}

CDemo::~CDemo()
{
    delete ui;
}

bool CDemo::LoadDll()
{
    QString sPath = QCoreApplication::applicationDirPath(); // exe文件所在路径
    sPath += "/MyDll.dll"; // 动态库的名字
    m_lib.setFileName(sPath);
    return m_lib.load();
}

bool CDemo::Resolve(const QString &sFuncName, QFunctionPointer &pfFunc)
{
    if (!m_lib.isLoaded())
    {
        return false;
    }

    pfFunc = m_lib.resolve(sFuncName.toStdString().c_str());

    if (nullptr == pfFunc)
    {
        qDebug() << QString("CDemo::Resolve: Failed to resolve function:%1 %2").arg(sFuncName).arg(m_lib.errorString());
        return false;
    }

    return true;
}

void CDemo::MyActive()
{
    QFunctionPointer pfFunc = nullptr;

    if (!Resolve("MyActive", pfFunc))
        return;

    ((pfMyActive)pfFunc)();
}

运行后的效果

如果一个Qt Creator同时打开了库的工程和调用库的工程,那么通过断点可以进入库中的函数查看对应数据的信息

三.认识动态链接库的后缀名

1、 .dll (Dynamic-Link Library)

1>用途: 动态库(Dynamic Library)
2>操作系统: Windows
.dll 文件是Windows操作系统下的动态链接库。动态库在运行时被加载到内存中,允许多个程序共享相同的库代码,从而节省内存。

2、 .lib

1>用途: 静态库(Static Library)或导入库(Import Library)
2>操作系统: Windows
在Windows上,.lib 文件有两种用途:一种是静态库,直接将库的代码编译到应用程序中;另一种是导入库,用于在编译时链接动态库(.dll 文件),导入库包含动态库的符号信息而不是实际代码。

3、 .a

1>用途: 静态库(Static Library)
2>操作系统: Unix-like系统(如Linux、macOS)
 .a 文件是Unix-like系统下的静态库。静态库在编译时被链接到应用程序中,从而在运行时不需要外部库的支持。

4、 .so (Shared Object)

1>用途: 动态库(Dynamic Library)
2>操作系统: Unix-like系统(如Linux)
 .so 文件是Unix-like系统下的动态库。与Windows的.dll类似,.so文件在运行时被加载到内存中,多个程序可以共享这些库文件。
 

四.如何选择库类型

静态库: 如果你希望所有的库代码都包含在应用程序的可执行文件中,且不希望在运行时依赖外部库,可以使用静态库(.lib 或 .a)。这通常会导致较大的可执行文件,但部署较为简单,因为不需要额外的库文件。
动态库: 如果你希望多个应用程序共享同一套库代码,从而节省内存和磁盘空间,可以使用动态库(.dll 或 .so)。这通常会使得应用程序的可执行文件较小,但需要在运行时确保动态库可用。

五.在Qt中生成库

可以通过一开始建立工程的时候去配置,但这些本质上都是在.pro中添加信息,那么这里直接可以通过修改项目文件(.pro 文件)中的配置来实现。例如:

静态库:
TEMPLATE = lib
CONFIG += staticlib

动态库:
TEMPLATE = lib
CONFIG += dll

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Linux中,Qt Creator是一个强大的集成开发环境,用于开发跨平台的应用程序。在使用Qt Creator创建调用动态库时,需要经过以下几个步骤: 1. 首先,在Qt Creator中新建一个工程。选择“Dynamic Library”作为项目类型。 2. 在工程文件中,定义需要暴露给其他程序使用的函数和类。可以在.h头文件中声明函数和类的接口,并在.cpp源文件中实现相应的功能。 3. 编译生成动态库文件。在Qt Creator中,可以点击“构建”按钮编译和链接生成动态库文件。生成的动态库文件一般以.so(shared object)为扩展名。 4. 创建一个新的可执行程序项目,并引用该动态库。在新的项目中,需要在.pro文件中添加对动态库的依赖关系。例如,可以使用LIBS += -L/path/to/library -lmylibrary来指定动态库的路径和名称。 5. 在可执行程序中调用动态库中的函数或类。在主函数或其他需要使用动态库的地方,可以直接调用动态库中定义的函数或类,实现相应的功能。 值得注意的是,动态库调用中还需要注意以下几点: 1. 在调用动态库函数时,需要先加载动态库。可以使用dlopen函数加载动态库文件,并使用dlsym函数获取需要调用的函数指针。 2. 调用动态库中的函数时,需要根据函数的参数类型进行适当的类型转换。因为动态库函数的参数类型可能与调用者的类型不完全匹配。 3. 在完成动态库的使用后,需要使用dlclose函数关闭对动态库的引用,释放相关资源。 总结来说,使用Qt Creator在Linux中创建调用动态库需要进行项目的设置、编译生成动态库文件,然后在其他项目中引用动态库调用其中定义的函数或类。同时,还需要注意动态库的加载和关闭过程,以确保正确使用动态库功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值