vs添加第三方库详解

2023-11-18


以前总是不知道怎么使用第三方库,每次想学习一个库进行开发,总是遇到各种各样的问题,由于自己能力不够,不知怎么解决,网上也没有找到适合自己的解决方法,最后都放弃。比如之前想学vlc视频程序,想学duilib界面库,因为总感觉mfc的界面太丑,想学boost库等,可是之前对一些知识理解不到位,总是挫败告终,此时特意记录下来,以免以后忘记。

本文主要讲使用第三方库或自己编写的库的常规流程,从引入到最后成功调用。当然你使用第三方库的时候,还会遇到其他的问题导致编译不过,或者使用时候出错,这个会在另一篇博客中介绍。

本文主要以自己编写一个库作为例子,介绍每一个过程的细节,其实第三方库也是这么一个过程,作为程序员,举一反三的能力,相信还是没问题的。

一、编写库所生成的文件(核心文件)

库工程生成的三个核心文件是:xxx.h、xxx.lib、和xxx.dll。注意:并不是一定要同时存在三个文件,具体用哪个或哪两个文件,要根据你使用的情况而定,显式动态调用只需xxx.dll即可,隐式动态调用则必须要xxx.h和xxx.lib。
本文以生成一个math的库工程为例,注意仅仅是演示作用,自己实际开发时候尽量避免与现有的库同名,否则命名冲突。
1.1、新建win32项目,名称:math,点确定,选择dll,完成。
在这里插入图片描述
1.2、在mian.cpp(或者添加一个xxx.h的头文件和xxx.cpp的源文件,道理一样)添加以下代码。然后编译,生成文件即可。
在这里插入图片描述
1.3、看看生成了什么,去到debug目录下,生成了math.dll,和math.lib。头文件在哪?其实此时的main.cpp 就是所谓的头文件,只是懒得改罢了,所以此时的三个核心文件是:main.cpp,math.lib和main.dll。
在这里插入图片描述

二、两种使用库的方式。此时添加一个Pro工程调用这个库。

在这里插入图片描述
有了以上三个文件,有了新建的pro工程,要什么调用Add函数呢?这就是接下来要讲的,两种使用库的方式:隐式动态调用和显式动态调用。
2.1、隐式动态调用:
隐式动态调用:简单讲,就是告诉编译器,函数声明在头文件,函数定义在lib中。
隐式动态调用所需文件:xxx.h,和xxx.lib,两者缺一不可。隐式动态调用,有两种导入方式:
第一种导入方式:
1、包含头文件路径;注意,此时是main.cpp的路径,你的应该是xxx.h路径,即函数声明的文件路径
2、包含库文件路径;注意,刚才生成的lib的路径
3、添加库文件名称;(声明所在)
4、在调用的位置添加头文件;(定义所在)
5、将math.dll丢到Pro.exe所在目录下。

包含头文件和库路径
在这里插入图片描述
添加链接库的名称
在这里插入图片描述

在Pro工程中使用Add函数吧!看,调用成功!
在这里插入图片描述
第二种导入方式
1、包含头文件路径;
2、添加头文件名称;
3、使用#pragma comment(lib,“库名称”);
4、将math.dll丢到Pro.exe所在目录下。
先删除上面的配置文件,然后添加头文件路径。
在这里插入图片描述
在这里插入图片描述
引入头文件,添加#pragma comment(lib,“库名称”)。并查看结果,注意库的路径名称。实际中一般处理方法是,库路径包含到math.lib的路径,#pragma comment(lib,“math.lib”),此处故意为之,目的是让新手能看懂。
在这里插入图片描述
2.2、显式动态调用:
显式动态调用:简单讲,当exe执行,需要调用dll的时候,加载这个dll,并找到对应函数的地址,然后调用方法。
导入方式:很粗暴,只需要dll即可,并不需要.h和.lib,这两个是在编译的时候告诉exe,dll中函数的地址,而显式调用,直接在运行时找函数地址,所以不需要提前告诉exe,函数在哪。
1、include <windows.h> ;此头文件中定义导入库的函数:LoadLibrary()
2、HMODULE hMod = LoadLibrary(“math.dll”);//dll路径
3、FUNA addfun = (FUNA)GetProcAddress(hMod, TEXT(“Add”));//直接写调用的函数名:Add,返回函数地址
4、addfun(a, b);直接调用。
在这里插入图片描述

三、库导出函数时候的细节情况

1、在隐式动态调用的时候,_declspec(dllexport) int Add(int a,int b),就可以调用动态库
2、在显式动态调用的时候,必须添加extern “C”,如extern “C”_declspec(dllexport) int Add(int a,int b),否则在寻找函数指针时失败。原因为C++有函数重载,编译器会改编函数名称,当extern "C"之后,就用C的方式命名,就能找到函数地址,其中还涉及到函数调用约定等知识,在后续再研究,再记录下来。在隐式动态调用中没有出现这个问题,是编译器帮忙做了一些工作,会绑定改名后的地址,所以不会失败。

四、新建工程使用这个库

具体过程在第二部演示,不再展示,放在第二部分讲,是让新手更清楚显式和隐式调用之间的区别,怎么找到函数声明,怎么找到函数定义,或者怎么找到程序运行时的函数地址。

源码请看https://download.csdn.net/download/littlelittlefish_xyg/10716835

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vs添加第三方库详解 的相关文章

  • C++学习(四十二)缓冲:满缓冲 行缓冲 无缓冲

    类型 说明 输出情况 满缓冲 I O操作只有在缓冲区被填满后才会进行 1 缓冲区满 2 刷新数据 flush 3 关闭文件 行缓冲 遇到换行符或者缓冲区满后才会执行I O操作 1 缓冲区满 2 刷新数据 flush 3 关闭文件 4 遇到换
  • 修改Nuget缓存包下载路径

    一 打开NuGet config文件 该文件通常在C Users Username AppData Roaming NuGet下 二 添加设置 添加设置 value值设置为自己想要的路径
  • C++基础(10)——函数模板和类模板

    前言 本文主要介绍了C 中函数模板和类模板基本知识 6 1 函数模板 模板函数的定义 template
  • C++之:struct和class的区别

    一 数据封装和成员访问权限 1 结构体 struct 在struct中 默认的成员访问权限是public 这意味着 在结构体外部 我们可以直接访问其成员变量和成员函数 下面是一个简单的例子 struct Point int x y Poin
  • C++学习(四十一)stderr stdout

    stdout 标准输出设备 stderr 标准错误输出设备 两者默认向屏幕输出 但如果用转向标准输出到磁盘文件 则可看出两者区别 stdout输出到磁盘文件 stderr在屏幕 在默认情况下 stdout是行缓冲的 他的输出会放在一个buf
  • typedef struct

    用途一 定义一种类型的别名 而不只是简单的宏替换 可以用作同时声明指针型的多个对象 比如 char pa pb 这多数不符合我们的意图 它只声明了一个指向字符变量的指针 和一个字符变量 以下则可行 typedef char PCHAR PC
  • ##顺序表 编码##

    ifndef LIST H define LIST H class List public List int size List 析构函数 void ClearList 清空线性表 bool ListEmpty 判断线性表是否为空 int
  • C++——并发之std::async使用注意的坑,以及promise,future

    promise背景1 promise背景2 async 1 async 与promise future 1 1 async以及获取时间 async函数如下所示 template
  • 内联函数及其注意事项

    default argument 是编译器记住了default argument 但是运行时还是要两个参数的 编译器看到了原型声明 可以有default argument值 所以编译器替你补上了 建议 不要使用default argumen
  • c++面对对象基础知识

    一 类的定义格式 class calss name private data member declarations public member functions 二 构造函数 1 在程序声明对象时 将自动调用构造函数 2 c 提供两种构
  • C++之对封装、继承、多态的理解

    目录 一 对封装 继承和多态的简单理解 二 举例 1 封装的例子 2 继承的例子 3 多态的例子 三 代码实现 1 封装 C 或Java实现 2 继承 C 或Java实现 3 多态 C 或Java实现 四 以一个简单的实例 剖析 封装 的实
  • MySQL connector/C++ 连接mysql效率低下解决

    这个问题 说解决也不算是被解决了 只能是让数据库插入的时候不会有像直接插入一样有那么多的问题了 我的解决方法是 开启mysql的事务 开始我也不知道是不是我的mysql配置优化的问题 WAMP统一安装 无限默认下一步的 在用PHP测试的时候
  • 1-2 VS2019常用调试方法(断点设置、条件断点、调试按钮、逐过程、逐语句、监视变量、快速监视)

    文章目录 前言 1 打印数据 2 普通断点 2 1断点快捷键 3 条件断点与条件追踪 4 单步调试 5 添加监视 5 1快速监视 前言 主要调试方法 1 打印数据 2 普通断点 3 条件断点与条件追踪 4 单步调试 5 添加监视 1 打印数
  • STL——vector以及emplace_back分析

    1 这里需要注意凡是连续空间的容器都提供operator 是为了数组操作 2 back 应该是 end 1 3 vector的大小为12 vector的迭代器为指针 1 emplace back 1 相比push back 如果传入临时对象
  • vector string及数组使用

    使用vector输入字符串并输出字符串 include
  • vs添加第三方库详解

    vs添加第三方库详解 一 编写库所生成的文件 核心文件 二 两种使用库的方式 此时添加一个Pro工程调用这个库 三 库导出函数时候的细节情况 四 新建工程使用这个库 以前总是不知道怎么使用第三方库 每次想学习一个库进行开发 总是遇到各种各样
  • C语言中关键字const、static、volatile的用法分析

    1 const 作为一个程序员 我们看到关键字const时 首先想到的应该是 只读 因为 它要求其所修饰的对象为常量 不可对其修改和二次赋值操作 不能作为左值出现 看几个例子 const int a 同上面的代码行是等价的 都表示一个常整形
  • 突如其来的C#重新学习(2)

    突如其来的C 重新学习 2 关于Main入口点的问题 Main在C 中不能单独声明 所以必须声明在同一个类中 而且必须声明静态方法 返回可以是void或者int 正常执行应当返回0 对于一个命名空间之内有很多的类的情况下 就可以手动选择从哪
  • C#各种结束进程的方法详细介绍

    转自http www cnblogs com zjoch p 3654940 html Process类的CloseMainWindow Kill Close Process CloseMainWindow是GUI程序的最友好结束方式 从名
  • 对于单向链表的排序与去重

    include bits stdc h using namespace std struct node int num node next class Chain public Chain head tail new node void G

随机推荐

  • python Django web 框架 (二十)之ORM

    Django之模型层第一篇 单表操作 一 ORM简介 我们在使用Django框架开发web应用的过程中 不可避免地会涉及到数据的管理操作 如增 删 改 查 而一旦谈到数据的管理操作 就需要用到数据库管理软件 例如mysql oracle M
  • 拿什么拯救你? rm -r

    天雷滚滚 天雷滚滚 天雷滚滚 作为一个Linux程序员 你能碰到的最伤心的事情 莫过于 编译了一整天的工程 不小心被rm r掉了 错误的执行了rm r 把文件系统都删除了 在嵌入式板子和PC之间切换的时候 不小心删错了目标 不要说你没有遇到
  • C++之数组

    C 基础 3 数组 3 1 一维数组 3 1 1 一维数组定义方式 3 1 2 一维数组数组名 3 2 二维数组 3 2 1 二维数组定义方式 3 2 2 二维数组数组名 3 数组 3 1 一维数组 概述 数组就是一个集合 里面存放了相同类
  • 进程、线程、管程、纤程、协程概念以及区别

    进程 进程是指在操作系统中能独立运行并作为资源分配的基本单位 由一组机器指令 数据和堆栈等组成的能独立运行的活动实体 进程在运行是需要一定的资源 如CPU 存储空间和I O设备等 进程是资源分配的基本单位 进程的调度涉及到的内容比较多 存储
  • WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connec

    python安装包错误 网络原因 直接改用阿里云镜像 然后再安装 pip config set global index url https mirrors aliyun com pypi simple 这就修改成功 接下来正常执行安装命令
  • docker 编辑容器内文件

    docker 编辑容器内文件 近期在学习docker 为编辑容器中文件 可以使用以下几种方法 特此记录 方法1 在容器中修改 使用vi命令编辑文件 注 如果vi命令没有 可以使用yum y install vim或者apt get inst
  • js-table2excel

    eslint disable let idTmr const getExplorer gt let explorer window navigator userAgent ie if explorer indexOf MSIE gt 0 r
  • 流程图中的实线_XMind如何在流程图中绘制实线箭头?XMind使用技巧

    如何利用xmind制作自己的思维导图 你好 建议你可以这样试试看 打开画图工具点击上方栏目 思维导图 在跳转专的页面点击 立即属体验 进入在线绘制界面 在画布的四周有很多的工具栏 这些在绘制的过程中都是可以使用的 首先 将中心主题进行确立
  • Java中StringBuffer类常用方法介绍

    StringBuffer类的介绍 StringBuffer是字符串缓存区 当new的时候是在堆内存创建了一个对象 底层是一个长度为16的 字符数组当调用添加的方法时 不会再重新创建对象 在不断向原缓冲区添加字符 查看字符串缓存区容量和长度
  • 快速傅氏变换之旅(一) 概念简介 3

    1 蝶形变换 普通的FFT算法称为基2的FFT算法 这种算法的核心是蝶形变换 长度为n 2 k1的变换共需要做 k1 n 2 次蝶形变换 如上图所示 若需变换数据表示为一个复数数组c 则每次蝶形变换有2个输入 c i c i s 两个输出
  • JS解密日记

    前言 JS混淆是通过改变JS代码的语法结构来使代码难以阅读和理解的技术 然而 请注意 混淆并不能真正保护您的代码 因为它仍然可以被解密和恢复其原始形式 直接上源代码 eval function p a c k e r e function
  • C11:mutex和lock_guard的使用.

    在C 11中 引入了有关线程的一系列库 且都在std命名空间内 下面演示一个使用线程的例子 非常的简单 引入了thread和mutex头文件 include
  • 攻防世界 inget

    打开网页提示 Please enter ID and Try to bypass 输入id绕过 尝试一下万能钥匙 尝试要不要符号闭合 http 61 147 171 105 49280 id 1 or 1 1 加个单引号成功 http 61
  • 【菜鸟C++学习杂记】ASCII码转换和显示

    笔者今年刚考上华东某高校的计算机研究生 本科虽是计算机学院 但期间主攻C 和Unity游戏开发 研究生属于小跨到计算机科学与技术 目前在进行硕导给的假期期间学习C 的任务 此类杂记主要记录下编码过程遇到的一些有趣的小知识 在某网课遇到了一个
  • 运用PL/SQL从1~100(包含边界)偶数之和

    1 第一种 方式实现 代码 set serveroutput on declare number integer 0 i integer 0 begin while i lt 100 loop number number i i i 2 e
  • 巴比特

    摘要 据 科创板日报 报道 当地时间5月9日 Meta宣布开源了一种可以横跨6种不同模态的全新AI模型ImageBind 包括视觉 图像和视频形式 温度 红外图像 文本 音频 深度信息 运动读数 由惯性测量单元或IMU产生 ImageBin
  • 为什么需要进程间通信??

    进程是一个独立的资源分配单元 不同进程 这里所说的进程通常指的是用户进程 之间的资源是独立的 没有关联 不能在一个进程中直接访问另一个进程的资源 例如打开的文件描述符 但是 进程不是孤立的 不同的进程需要进行信息的交互和状态的传递等 因此需
  • 微信公众号支付H5调用支付详解

    原文地址 http blog csdn net fengshizty article details 45564685 微信公众号支付 最近项目需要微信支付 然后看了下微信公众号支付 虽然不难 但是细节还是需要注意的 用了大半天时间写了个d
  • [Java]JAVA获取实体与List 数组的转换

    public class BeanToArray private String beanNames private Object values public BeanToArray public BeanToArray String bea
  • vs添加第三方库详解

    vs添加第三方库详解 一 编写库所生成的文件 核心文件 二 两种使用库的方式 此时添加一个Pro工程调用这个库 三 库导出函数时候的细节情况 四 新建工程使用这个库 以前总是不知道怎么使用第三方库 每次想学习一个库进行开发 总是遇到各种各样