Qt中纯C++项目发布为dll的方法(超详细步骤)

news2024/11/19 4:41:57

目录

  • 一般创建方法
  • 导出普通函数的方法&调用方法
  • 导出类及其成员函数的方法&调用方法

众所周知,我们可以将C++项目中的类以及函数导出,形成 .dll 文件,以供其他程序使用,下面将说明Qt环境下的使用方法。

首先创建共享库,步骤如下:

 

 

下一步会出现类对话框等等,不用管它,直接点击创建即可,稍后再将类都删了。

创建好以后你会发现有一个包含global的头文件,这个文件中定义了__declspec(dllexport)、__declspec(dllimport)等,也可以删掉(如果要按照下面的方法的话,删掉即可)。

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(Qt实战项目视频教程+代码,C++语言基础,C++设计模式,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

接下来还有重要的一步,请在.pro文件中,加入

CONFIG += dll //即使你的代码中写成了 CONFIG += staticlib,也要改过来

接下来就开始我们具体的的创建方法吧!

按照导出dll的的操作划分,有两种模式:

  • 导出普通方法(导出后可静态调用,也可动态调用)

首先是头文件内容:

头文件:
在方法声明时,前面加上__declspec(dllimport),也可用#define定义,看代码:
//为了和将来用到的程序中公用一个头文件,创建dll时用到的是__declspec(dllexport),而使用dll时用到__declspec(dllimport),完全可以各自写一下
#define TESTDLLSHARED_EXPORT __declspec(dllexport)
#ifdef TESTDLLSHARED_EXPORT
#else
#define TESTDLLSHARED_EXPORT __declspec(dllimport)
#endif

//下面我要定义4个普通函数:
TESTDLLSHARED_EXPORT int test1();

TESTDLLSHARED_EXPORT int test2(void);

TESTDLLSHARED_EXPORT int test3(int a);

TESTDLLSHARED_EXPORT int test4(int a,int b);

然后在对应的cpp源文件中实现test1、test2、test3、test4这几个方法(为了简单,我只输出了一句话):

.cpp源文件://记得加上上面的头文件
//记得加上iostream头文件,不然cout不能用

int test1()
{
    std::cout<<"test1"<<std::endl;
}

int test2(void)
{
    std::cout<<"test2"<<std::endl;
}

int test3(int a)
{
    std::cout<<"test3"<<std::endl;
}

int test4(int a,int b)
{
    std::cout<<"test4"<<std::endl;
}

接下来就可以创建了,创建成功后(创建失败请仔细检查,代码已验证过),你会在你的项目输出目录下找到一个和项目名称一致的.dll文件。

OK!接下来我们来使用这个dll:

使用dll时有两种调用方法,一种是静态调用,一种是动态调用。

  • 静态调用

首先,创建一个常规的C++项目,将上面生成.dll复制到你的项目输出目录中(也就是和.exe文件在一起);

接下来,打开常规C++项目中的.pro文件,加入详细的.dll文件地址,格式如下

LIBS += 项目输出路径\dll文件全称

如我的就是

LIBS += D:\Desktop\Go\C++learnProgram\Qt\build-test_dll-Qt-Release\release\HpTickDll.dll
D:\Desktop\Go\C++learnProgram\Qt\build-test_dll-Qt-Release\release是我的项目输出路径,HpTickDll.dll是我的dll文件,使用时改动一下就好

接下来,将创建.dll文件时的头文件复制到当前项目路径下,并添加到项目中,注意:如果你没有按照我上面的#define条件定义方式,请重新写__declspec(dllimport)。

接下来,在.cpp文件中包含该头文件,就可以尽情地使用之前的函数了,如直接用test1()等等,就和平时编写一样的。

  • 动态调用

!!!特别注意:我们在创建时没有用到extern "C",也没有用到.def 文件保持函数名不变(尝试了很多次也不会用.def文件,会的欢迎留言),因此动态调用时函数名要改!因为编译器已经将函数名改了!

So,你一定会问我们怎么知道dll中的函数名变成啥了?不要着急,网上直接搜“.dll查看器”,遍地都是,下载下来后,选择我们刚才的.dll文件就可以看了,下面是我们的这几个函数test1、test2、test3、test4的新名称(你的可能和我的不一样哦):

请注意看红色框中的部分(不要管其他的,我的文件里面还有其他东西),这就是四个函数在.dll文件中的名称,我小小地猜测了一下,后面的v代表参数为void类型,i的个数代表int类型参数的个数,前面的字母就不太清楚了(注意:参数个数并未正确列出,不过我们只需要正确的函数名,不影响)。

OK!这就好办了!看步骤:

同样是创建一个常规C++项目,不同的是.pro文件中不用加“LIBS += 项目输出路径\dll文件全称”这句话了。

接下来在.cpp文件中写主代码(不用添加之前的头文件):

#include <iostream>
#include <windows.h>

int main()
{
    //首先定义函数指针,用来接收不同参数的函数
    typedef int (CALLBACK *Fucv)();
    typedef int (CALLBACK *Fuci)(int);
    typedef int (CALLBACK *Fucii)(int,int);
    //获得.dll文件的句柄,需要头文件windows.h的支持
    HINSTANCE hdll=LoadLibrary(L"testDll.dll");     //L指宽字符串,若不写L,则会出现错误,详情请自查

    //注意这里要用.dll文件中的函数名
    Fucv t1=(Fucv)GetProcAddress(hdll,"_Z5test1v");
    Fucv t2=(Fucv)GetProcAddress(hdll,"_Z5test2v");
    Fuci t3=(Fuci)GetProcAddress(hdll,"_Z5test3i");
    Fucii t4=(Fucii)GetProcAddress(hdll,"_Z5test4ii");

    //现在的t1就执行的test1的功能,以此类推
    t1();
    t2();
    t3(1);
    t4(1,2);

    FreeLibrary(hdll);

    return 0;
}

以上就是普通函数创建.dll和使用.dll的方法,看起来动态调用是不是很麻烦?但它有许多优点(请自查),而且据说这里的函数名可以利用.def文件实现不改变名称,省去好多麻烦,但是我尝试了各种方法,如在.pro中利用DEF_FILE添加.def文件还是不行55555,会的可以留言哦!

  • 导出类及其成员函数(导出后可静态调用。暂时不会动态调用,某些书上说类不支持动态调用,网上有说在类中写一个方法返回类对象,但是个人认为这种做法是不对的,因为此时肯定是用自己定义的函数指针去定义这个返回类对象方法,不可能成功【已验证】,当然或许还有更好的方法,有知道的欢迎交流哈)

对于类的话,创建时:在class的后面,类名的前面加上定义的__declspec(dllexport);使用时,换成__declspec(dllimport),也可以参照前面的#define条件定义法。举例:

#define HPTICKDLLSHARED_EXPORT __declspec(dllexport)
#ifdef HPTICKDLLSHARED_EXPORT
#else
#define HPTICKDLLSHARED_EXPORT __declspec(dllimport)
#endif

class HPTICKDLLSHARED_EXPORT HpTickDll  //我在这里定义了类HpTickDll
{   
public:
    int  Start();                       //注意成员函数之前不用加HPTICKDLLSHARED_EXPORT
    int  GetTime();

private:

    LARGE_INTEGER li;
    LONGLONG start, end, freq;
    int useTime;
};

静态调用的方法和普通函数一样,直接可以使用类及其成员函数(别忘了添加头文件),就不细说了。

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(Qt实战项目视频教程+代码,C++语言基础,C++设计模式,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1109717.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

吐血整理,服务端性能测试中间件-项目集成redis实战,一篇打通...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Linux下Redis安装…

《小狗钱钱》阅读笔记(六)

目录 幼儿园最开始的作用不是让小朋友受教育&#xff0c;而是为了提供一个场所让小朋友免于被剥削 弗里德里希福禄贝尔 早期 其实那些有大作为的人&#xff0c;你看到他们的时候&#xff0c;你看&#xff0c;大多小时候都是受到过很多挫折的&#xff0c;我不是说&#xff0c…

安装thinkphp6并使用多应用模式,解决提示路由不存在解决办法

1. 安装稳定版tp框架 composer create-project topthink/think tptp是安装完成的目录名称 &#xff0c;可以根据自己需要修改。 如果你之前已经安装过&#xff0c;那么切换到你的应用根目录下面&#xff0c;然后执行下面的命令进行更新&#xff1a; composer update topthin…

HTML5+CSS3小实例:网页底部间隔波浪动画特效

实例:网页底部间隔波浪动画特效 技术栈:HTML+CSS 效果: 源码: 【html】 <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content…

算法第一关-黄金挑战

环形链表 描述 : 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 LeetCode 141.环形链表 : 141. 环形链表 牛客 BM6 判断链表中是否有 : 分析 : 用HashS…

接口测试实战讲解

本次实战&#xff0c;我是从网上找的接口测试项目&#xff0c;该项目提供了详细的接口文档&#xff0c;我们可以通过学习接口文档来设计测试用例&#xff0c;最后再使用Jmeter进行实战。总的来说&#xff0c;这个项目很适合用来练手&#xff0c;项目网址&#xff1a;https://ww…

Python接口自动化 —— Json 数据处理实战(详解)

简介 上一篇说了关于json数据处理&#xff0c;是为了断言方便&#xff0c;这篇就带各位小伙伴实战一下。首先捋一下思路&#xff0c;然后根据思路一步一步的去实现和实战&#xff0c;不要一开始就盲目的动手和无头苍蝇一样到处乱撞&#xff0c;撞得头破血流后而放弃了。不仅什么…

自学(黑客技术)——网络安全高效学习方法

前言 前几天发布了一篇 网络安全&#xff08;黑客&#xff09;自学 没想到收到了许多人的私信想要学习网安黑客技术&#xff01;却不知道从哪里开始学起&#xff01;怎么学&#xff1f;如何学&#xff1f; 今天给大家分享一下&#xff0c;很多人上来就说想学习黑客&#xff0c…

八股文学习四(kafka)

一. 消息中间件kafka (1)基本概念 (2) 生产者 生产者将消息发送到topic中去&#xff0c;同时负责选择将message发送到topic的哪一个partition中。通过round-robin做简单的负载均衡。也可以根据消息中的某一个关键字来进行区分。通常第二种方式使用的更多。 (3)消费者 消费模…

this指向输出题

&#x1f197;先简简单单来看一个小代码 var name "windowsName"console.log(this.name, 222)function fn() {var name Cherryconsole.log(this.name, 444);innerFunction()console.log(this.name, 333)function innerFunction() {console.log(this.name, 111)}}fn…

8年测试老鸟总结,APP自动化测试思路整理,跟着步骤快速撸码...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、开发语言选择 …

STM32 Debug查看const变量 在flash中存储地址

1.下面const数组&#xff0c;存储在flash中&#xff0c;通过map文件获取CH_value的数组首地址0x080014c8&#xff0c;或者debug中在函数中添加CH_value到Memory&#xff0c;获取数组在flash中存储的位置。

C++对象模型(17)-- 构造函数语义学:成员初始化列表

1、必须用初始化列表的场景 &#xff08;1&#xff09;成员变量是引用类型&#xff0c;必须在初始化列表中初始化。 &#xff08;2&#xff09;成员变量是const类型&#xff0c;必须在初始化列表中初始化。 &#xff08;3&#xff09;如果类继承自一个父类&#xff0c;并且父…

跨境商城源码部署(无货源模式,多语言,多货币)

在互联网发展的背景下&#xff0c;跨境电商成为了全球贸易的重要形式之一。跨境商城源码部署是指将跨境电商平台的源代码部署到服务器上&#xff0c;以便搭建一个完整的跨境商城网站。通过部署源码&#xff0c;可以实现无货源模式、多语言和多货币等功能&#xff0c;为用户提供…

Flutter的Constructors for public widgets should have a named ‘key‘ parameter警告

文章目录 问题描述问题原因修改方法详细解释 问题描述 Constructors for public widgets should have a named ‘key’ parameter. 如下图&#xff1a; 原本的代码 class MyTabPage extends StatefulWidget {override_MyTabPageState createState() > _MyTabPageState(…

多测师肖sir_高级金牌讲师___ui自动化之selenium001

一、认识selenium &#xff08;1&#xff09;selenium是什么&#xff1f; a、selenium是python中的一个第三方库 b、Selenium是一个应用于web应用程序的测试工具&#xff0c;支持多平台&#xff0c;多浏览器&#xff0c;多语言去实现ui自动化测试&#xff0c;我们现在讲的Sel…

软件工程与计算总结(二十)软件交付

软件交付是软件项目的结束阶段 &#xff0c;标志着软件开发任务的完成——其作为一个分水岭&#xff0c;区分了软件开发与软件维护两个既连续又不同的软件产品生存状态~ 在经历连续的辛苦工作之后&#xff0c;开发人员在胜利曙光之前难免会忽视软件交付阶段的一些工作——在准…

2022年亚太杯APMCM数学建模大赛C题全球变暖与否全过程文档及程序

2022年亚太杯APMCM数学建模大赛 C题 全球变暖与否 原题再现&#xff1a; 加拿大的49.6C创造了地球北纬50以上地区的气温新纪录&#xff0c;一周内数百人死于高温&#xff1b;美国加利福尼亚州死亡谷是54.4C&#xff0c;这是有史以来地球上记录的最高温度&#xff1b;科威特53…

Shiro安全框架登录验证实例解析

一、Shiro框架简单介绍 Apache Shiro是Java的一个安全框架&#xff0c;旨在简化身份验证和授权。Shiro在JavaSE和JavaEE项目中都可以使用。它主要用来处理身份认证&#xff0c;授权&#xff0c;企业会话管理和加密等。Shiro的具体功能点如下&#xff1a; &#xff08;1&#…

即刻报名,企业服务与新经济论坛亮点提前揭秘!

峰会官网已上线&#xff0c;最新议程请关注&#xff1a;doris-summit.org.cn 即刻报名 Doris Summit 是 Apache Doris 社区一年一度的技术盛会&#xff0c;由飞轮科技联合 Apache Doris 社区的众多开发者、企业用户和合作伙伴共同发起&#xff0c;专注于传播推广开源 OLAP 与实…