Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Qt中纯C++项目发布为dll的方法(超详细步骤)

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

作者头像
用户1198337
发布于 2018-01-19 03:21:50
发布于 2018-01-19 03:21:50
1.8K00
代码可运行
举报
文章被收录于专栏:我有一个梦想我有一个梦想
运行总次数:0
代码可运行

目录

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

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

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

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CONFIG += dll //即使你的代码中写成了 CONFIG += staticlib,也要改过来

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

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

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

首先是头文件内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
头文件:

在方法声明时,前面加上__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这几个方法(为了简单,我只输出了一句话):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.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文件地址,格式如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
LIBS += 项目输出路径\dll文件全称

如我的就是

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
LIBS += D:\Desktop\Go\C++learnProgram\Qt\build-test_dll-Qt-Release\release\HpTickDll.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文件中写主代码(不用添加之前的头文件):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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条件定义法。举例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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;
};

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-02-24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
dll生成和使用
dll文件的编译生成 创建项目Win32控制台应用程序 创建项目1.png 创建项目2.png 配置属性 项目/属性 配置属性.png
用户2929716
2018/08/23
1.2K0
dll生成和使用
C++ DLL 工程创建与使用
DLL,是 Dynamic Link Library的缩写,中文名 动态链接库。DLL是一个包含可由多个程序,同时使用的代码和数据的库。 本文简介DLL 概念,记录 DLL 工程创建与使用方法。 简介 动态链接库( Dynamic-link library,缩写为 DLL) 是微软公司在windows 系统中实现共享函数库概念的一种实现方式。所谓动态链接,就是把常用的公共函数封装到 DLL 文件中,当程序需要用到这些函数时,系统才会动态地将 DLL 加载到内存中使用。 调用方式主要分为两种:
为为为什么
2023/01/30
2K0
C++ DLL 工程创建与使用
c++DLL编程详解
DLL(Dynamic Link Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量、函数或类。在仓库的发展史上经历了“无库-静态链接库-动态链接库”的时代。 静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib中的指令都被直接包含在最终生成的EXE文件中了。但是若使用DLL,该DLL不必被包含在最终EXE文件中,EXE文件执行时可以“动态”地引用和卸载这个与EXE独立的DLL文件。静态链接库和动态链接库的另外一个区别在于静态链接库
拾点阳光
2018/05/10
2.3K0
exe调用DLL的方式
编写dll时,有个重要的问题需要解决,那就是函数重命名——Name-Mangling。解决方式有两种,一种是直接在代码里解决采用extent”c”、_declspec(dllexport)、#pragma comment(linker, "/export:[Exports Name]=[Mangling Name]"),另一种是采用def文件。
CN_Simo
2020/08/20
2.7K0
VC++DLL动态链接库程序
最近查找了一下VC++中关于编写DLL动态库的资料,主要是导出函数和导出类的编写。因为在实际项目开发中有时需要使用C++编写好DLL接口,控制设备,提供给其他语言如Nodejs、C#等使用。
ccf19881030
2019/07/10
1.4K0
C/C++中动态链接库的创建和调用
古时的风筝
2018/01/08
1.6K0
lib文件和dll文件的区别_dll2lib
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/167993.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/20
2.9K0
C语言dll文件的说明以及生成、使用方法
弗兰克的猫
2018/01/09
5.8K0
[C-C++]DLL之旅2 : 调用DLL(静态&动态加载)
原文链接:http://blog.csdn.net/humanking7/article/details/78586478
祥知道
2020/03/10
2.8K0
VC++的DLL应用(含Demo演示)
      在大学大一的时候学的是C,然后后来大二的时候专业又开了C++这个课程,然后再后来自己又自学了一点VC++,大三的时候也试着编写过一个MFC的最简单的窗口程序。到大四的时候,自己又做了一个GIS的项目,是用C#.NET来编写的,然后发现C#上手好容易,而且还大部分语法规则都沿用了C,C++的习惯,于是觉得C++实在是没有一点优势可言啊。但这个暑假的实习经历又改变了我的观点:C++在写窗口程序虽然麻烦,但是却什么能做,而且对比C#来说,对运行环境的要求不高,不用像C#程序在安装之前还要安装100M多的运行.NET环境。C++和C#各有优缺,目前我对它们俩的定位是:C++用来写一些底层的程序,比如驱动,或者是一些算法类型的函数接口,然后用C#来调用这些接口并进行界面设计。如何函数的实现跨语言呢?显然DLL是个很重要的内容,故在此对VC++的DLL模块进行介绍。
用户1170933
2022/05/10
9670
VC++的DLL应用(含Demo演示)
c#封装动态库_nginx调用so动态库
一直对动态库的封装理解不是很透彻,虽然之前写过一个Demo,不过并没有真正的理解。所以写下来,帮助自己理解下。
全栈程序员站长
2022/11/14
2.8K0
c#封装动态库_nginx调用so动态库
12、动态链接库,dll
动态链接库通常都不能直接运行,也不能接收消息。它们是一些独立的文件,其中包含能被可执行程序或其它DLL调用来完成某项工作的函数。只有在其它模块调用动态链接库中的函数时,它才发挥作用。
全栈程序员站长
2022/07/05
8490
12、动态链接库,dll
Win32编程之静态库编写与使用.动态链接库的编写与使用
  静态库其实就是解决模块开发的一种解决方案.在以前.我们写代码的时候.每个人都可以独立写一个项目.但是现在不行了.一个项目往往要很多人一起去编写.而其中用到的技术就类似于静态库.
IBinary
2022/05/10
7550
Win32编程之静态库编写与使用.动态链接库的编写与使用
【Example】C++ 接口(抽象类)概念讲解及例子演示
C++ 和 Java 不同的是,C++ 没有 interface 关键字。对于很多新手来说,C++ 当中接口的概念不容易像 Java 当中那样被理解。
芯片烤电池
2022/04/27
1.8K0
【操作系统】动态链接库
DLL就是整个windows操作系统的基础。动态链接库不能直接运行,也不能接收消息。他们就是一些独立的文件。
半生瓜的blog
2023/05/13
8170
【操作系统】动态链接库
Windows Api学习笔记-动态连接库(DLL)的使用
#include <windows.h> #include <iostream> #include "12dll.h" using namespace std; #pragma comment(lib,"12Dll")//要链接到什么库文件 void main() { //CMy12Dll a; cout<<fnMy12Dll()<<endl; char b; cin>>b; } VS2008 新建WIN32项目 选择动态连接库 应用程序类型为:WINDOWS 应用程序 附加选项为:导出符号 d
liulun
2022/05/09
6150
关于opentelemetry-cpp社区对于C++ Head Only组件单例和符号可见性的讨论小记
前段时间有人在 opentelemetry-cpp 提出了api组件在动态库中单例无法工作的 issue ,( https://github.com/open-telemetry/opentelemetry-cpp/issues/1520 ) 。
owent
2023/03/06
1.1K0
VS2010编写动态链接库DLL和单元测试,转让DLL测试的正确性
本文将创建一个简单的动态库-link,谱写控制台应用程序使用该动态链接库,该动态链接库为“JAVA调用动态链接库DLL之JNative学习”中使用的DLL,仅仅是项目及文件名不同。
全栈程序员站长
2022/07/05
1.3K0
VS2010编写动态链接库DLL和单元测试,转让DLL测试的正确性
白加黑免杀制作(详细)
最近被微步的一篇文章吸引了,里面讲到银狐通过自解压白 exe + 黑 dll 执行截取主线程添加自启动,发现 dll 与普通的免杀有很大的不同,决定自己尝试一下,虽然我之前没有做过白加黑免杀,感觉应该不会太难,但是当我真正尝试的时候才发现很多问题,如:
Creaper
2023/11/20
7.4K2
白加黑免杀制作(详细)
python 调用dll
首先用visual studio写个dll。 // TestDll.cpp : Defines the entry point for the DLL application. //
全栈程序员站长
2021/08/13
2.6K0
相关推荐
dll生成和使用
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文