qt使用动态库(DLL)

本文主要讲解在QT开发环境中如何使用VC生成的DLL及QT自身生成的DLL。至于其它情况本文不作讨论。

连接库分为2种

(1)动态连接库,通常有.h .lib .dll三个文件,功能实现在dll中

(2)静态连接库,通常有.h .lib二个文件,功能实现在lib中

由上可以看出动态库的lib和静态库的lib文件是不同的。

如果使用生成连接库的开发环境与使用连接库的开发环境相同,一般不会出什么问题,如VC写的连接库

(包括动态库和静态库)还在VC中用一般不会有什么问题的。有时候我们需要DLL跨开发环境,如以前VC下的

DLL想在QT中用。有网友说QT不支持VC生成的静态库,所以只测试QT使用动态库的情况。

【先看VC生成的DLL】

使用VC6建立Win32 dynamic-link library工程,工程中只有两个文件,编译即可生成DLL和LIB

////////////////////////////////// MFCDLL.h  /////////////////////////////////////
#ifndef _MFCDLL_H
#define _MFCDLL_H

#ifdef __cplusplus
extern "C" {
#endif

#ifdef DLL
    // do nothing
#else
#define DLL __declspec(dllimport)
#endif

DLL void hello();
DLL int add(int a, int b);

#ifdef __cplusplus
}
#endif

#endif
////////////////////////////////// MFCDLL.cpp  /////////////////////////////////////
#define DLL __declspec(dllexport)
#include "MFCDLL.h"
#include <windows.h>

void hello()
{
::MessageBox(NULL, "hello world!",
"greeting", MB_OK);
}

int add(int a, int b)
{
return a + b;
}

【使用QT生成DLL】使用QT建立动态库工程,编译即可得到DLL(无LIB文件)

////////////////////////////////// qtdll_global.h  //////////////////////////////
#ifndef QTDLL_GLOBAL_H
#define QTDLL_GLOBAL_H

#include

#if defined(QTDLL_LIBRARY)
#  define QTDLLSHARED_EXPORT Q_DECL_EXPORT
#else
#  define QTDLLSHARED_EXPORT Q_DECL_IMPORT
#endif

#endif // QTDLL_GLOBAL_H
////////////////////////////////// qtdll.h  /////////////////////////////////////
#ifndef QTDLL_H
#define QTDLL_H

#include "qtdll_global.h"

class QTDLLSHARED_EXPORT QTDLL
{
public:
    QTDLL();

public:
    int add(int a, int b);
};

#endif // QTDLL_H
////////////////////////////////// qtdll.cpp  ///////////////////////////////////
#include "qtdll.h"

QTDLL::QTDLL()
{
}

int QTDLL::add(int a, int b)
{
    return a + b;
}

【QT显式加载VC生成的DLL】

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLibrary>
#include <QDebug>

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

    // DLL显式加载,只需要DLL文件即可,不需要.H和.LIB文件
    // 需要将DLL放到可执行目录中
    typedef void(*FUN1)();
    typedef int(*FUN2)(int, int);

    QLibrary lib("MFCDLL.dll");
    if (lib.load()) {
        qDebug() << "load ok!";

        FUN1 hello = (FUN1)lib.resolve("hello");
        FUN2 add = (FUN2)lib.resolve("add");
        if (hello) {
            qDebug() << "load hello ok!";
            hello();
        }
        if (add) {
            qDebug() << "load add ok!";
            qDebug() << add(3, 5);
        }
    } else {
        qDebug() << "load error!";
    }
}

【QT隐式加载VC生成的DLL】

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "lib/MFCDLL.h"
#include <QDebug>

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

    // DLL隐式加载,只需要.DLL .H和.LIB文件
    // 1需要将DLL放到可执行目录中
    // 2将LIB路径设置到项目PRO文件中
    // 3将头文件包含进来,如果不包含需要自已声明函数原型及来源(本质与包含头文件相同)
    hello();
    qDebug() << add(5, 6);
    qDebug() << "ok";
}

pro工程文件中要设置LIB文件路径

# lib文件路径
LIBS += "F:/lib/MFC_DLL_TEST_WITH_QT_2/lib/MFCDLL.lib"

【QT使用QT生成的动态库,隐式】

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include "lib/qtdll.h"

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

    // QT使用QT生成的DLL
    // 1. 包含头文件
    // 2. 在工程文件中指定lib路径
    // 3. 将动态库拷贝到可执行文件目录
    QTDLL dll;
    qDebug() << dll.add(3, 5);
}

pro工程文件中的设置

LIBS += "F:/lib/QT_DLL_TEST_WITH_DLL/lib/QTDLL.dll"
时间: 2024-08-02 15:53:47

qt使用动态库(DLL)的相关文章

基于Qt的动态库*.dll文件创建

有时候在做项目的时候我们需要将自己编写的类封装起来,Qt提供了一个很好的封装途径.下面将详细讲述一个简单的库的制作过程,最后再创建另外一个工程,在这个工程里面对封装的库进行调用,从而完成一个dll库从创建到调用的过程.谢谢大家指正! 第一步:先制作一个库文件. 1.首先新建一个工程,工程选项如下,我们要创建一个基于qmake的C++共享库. 2.选择库的类型和存放路径. 3.在"hellolib.cpp"中添加如下的代码,让库函数输出一行文字. 4.点击左下角的编译,如果没有错误就生成

MFC 关于动态库DLL引用CDialog的关键点

,在MFC的应用开发中,经常会遇到将部分功能以DLL动态库的方式进行封装调用,在调用的过程中应注意以下几点 1 设置当前资源句柄 在DLL中查找资源文件时,如需要将当前资源文件的handle设置成dll模块的hinstance. AfxGetResourceHandle() 查看当前资源句柄 AfxSetResourceHandle() 设置当前资源句柄 GetModuleHandle(“dll文件名”); 例示: HINSTANCE h1 = AfxGetResourceHandle(); H

Qt编写自定义控件插件开放动态库dll使用(永久免费)

这套控件陆陆续续完善了四年多,目前共133个控件,除了十几个控件参考网友开源的代码写的,其余全部原创,在发布之初就有打算将动态库开放出来永久免费使用,在控件比较完善的今天抽了半天时间编译了多个qt版本的动态库,和头文件一起打包放在百度网盘. 控件介绍 超过130个精美控件,涵盖了各种仪表盘.进度条.进度球.指南针.曲线图.标尺.温度计.导航条.导航栏,flatui.高亮按钮.滑动选择器.农历等.远超qwt集成的控件数量. 每个类都可以独立成一个单独的控件,零耦合,每个控件一个头文件和一个实现文件

动态库DLL中类的使用

一.DLL中类的导出 在类名称前增加 _declspec(dllexport)定义,例如: class _declspec(dllexport) CMath{ .... }; 通常使用预编译开关切换类的导入导出定义,例如: #ifdef DLLCLASS_EXPORTS #define EXT_CLASS _declspec(dllexport) //DLL #else #define EXT_CLASS _declspec(dllimport) //使用者 #endif class EXT_C

c++跨动态库DLL的内存分配与释放问题

先说结论: 1.如果两个DLL(或者EXE调用DLL)的CRT链接均为MD,则可以跨动态库分配和释放,如果一个是MT,另外一个是MD则会有问题. 2.利用虚函数的动态绑定技术,动态绑定分配释放内存的new和delete等,可以解决这个问题,例如shared_ptr.但如果shared_ptr包装是vector等类型,在调用和被调用中都涉及到vector的修改的话,仍然会有问题,因为两个地方都会有释放和分配. 似乎最好的办法还是用原始指针加数组长度的方式传递. 参见下面两个文章. 1.跨DLL的内

C#调用c++的动态库dll演示例程

1.首先编写c++动态库 extern "C" __declspec(dllexport) int __stdcall add(int x, int y) { return x + y; } extern "C" __declspec(dllexport) extern "C"使得在C++中使用C编译方式成为可能.在"C++"下定义"C"函数,需要加extern "C"关键词.用exte

关于32位和64位部署出现C#调用delphi动态库DLL不成功的问题

由于项目中调用了动态库,这些动态库放在C:\Windows\System32下面,但是当部署到了64位的机器上可能就有问题了,最近这个问题就纠结了半天,在本机32为系统上测试动态调用ddl成功了,部署到64位Window Server2008上面也没问题,可是为什么到了64位的WIN7系统上出了问题呢?        最后才发现原来原来是DLL的位置不对,那么DLL到底该放到那呢?        如果细心的你,你会发现在C:\Windows\目录下面有两个文件夹:System目录和System3

MFC的亚博静态库.lib、体育动态库.dll以及Unicode库示例

MFC亚博静态库使用下列体育命名约定: uAFXcWd.LIB . 库命名约定的说明符如下: 说明符 值和含义u (n) ANSI 或 (u)Unicodec 创建的计划类型:c=alld d=debug版本; release版本略去说明符默认值为生成用于 Intel 平台的调试版本 windows ANSI 应用程序的静态库:NAFXCWD.Lib. 下表列出的所有库是在 \ atlmfc \ lib 目录中包含预生成的静态库. 静态链接库命名约定: 库 说明NAFXCW.LIB MFC 静态

Java 加载动态库 dll 文件

不知道具体原理,但是,加载 dll 文件时,带路径或者更改 dll 文件的名字,都会报错.虽然库记载成功了,但是处女座认为这不可接受.于是有了这个解决方案. 在根目录为库创建软连接,然后使用 system.loadLibrary(“libname”) 来加载.事实证明,它时认软连接的. 上代码: import com.seapine.surroundscm.api.*; import java.lang.UnsupportedOperationException; import java.lan