以OpenCV库为例讲解如何在VS中配置第三方动态库

众所周知,出现.lib, .dll这种文件的原因是为了保护源代码,这个就不细说了。

正常情况下,你拿到的别人的第三方动态库(静态库调用方式这里不讲,有另外一篇文章)至少应该包含下面三种文件:

  1. .h文件,这个一般放在include这样字眼的文件夹下

  2. dll文件,这个一般放在bin这样字眼的文件夹下

  3. dll配套的动态lib文件,这个就一般放在lib这样字样的文件夹下

用OpenCV的开源库来举个例子看一下就知道了:

在这里插入图片描述bin文件夹里面放的都是dll文件;

lib文件夹里面放的都是伴随dll文件的动态lib文件;

staticlib文件夹里面放的才是真正的静态lib文件,和dll文件是独立的;

所以可以看出,lib文件是有静态lib和动态llib之分的。

visual studio 配置

好了,我们要配置就只需要用到这三个地方了,下面以VS2010为例开始讲解:

前言:

.dll也是可执行文件,所以对应的是可执行文件目录;

.h是头文件,需要通过#include这种方式引用的,所以对应的是包含目录;

.lib是库文件,所以对应的是库目录;

下面我们讲解的是一种全局配置的方法,也就是在你的VS中配置后,对所有的用这个VS新建的项目都有效。

三种文件的路径都是在“项目—属性—配置属性—VC++目录”这个下面配置:
在这里插入图片描述

  1. 头文件路径:VC++目录下的包含目录,把include文件夹路径,以及它下面的两个二级目录路径都放进去:

在这里插入图片描述

  1. lib文件路径:VC++目录下的库目录,把lib文件夹的路径放这里:
    在这里插入图片描述
    或者,在Linker时加入(不推荐- -,看的不爽而已)
    在这里插入图片描述

  2. dll文件路径:dll按理来说对应的是VC++目录下的“可执行文件目录”,但是我们不直接添加在这里,而是在系统的环境变量PATH下,
    在这里插入图片描述
    系统的环境变量配置完成后需要注销一下电脑。

这里的PATH对应的就是VS中VC++目录下的可执行文件目录,程序运行的时候就会在PATH指定的路径中进行寻找。PATH中也看到了诸如system32之类的文件夹,理论上你把dll文件复制到这个文件夹system32下,也是一样可以的,但是那么多dll都复制到这里面会很乱,所以你就把dll路径放到这里就可以了。

  1. 添加附加依赖项

上面只是把所有的需要用到的文件路径包含进来了,并没有指明要用到哪些lib文件,所以还需要在这里指明具体的文件名:

好了,配置完成了,写代码的时候include需要的头文件就行了。


第一部分:静态lib文件,动态lib文件和dll文件的区别

  1. 静态lib文件
    生成方式:vs项目属性中设置输出为Static library
    在这里插入图片描述

调用静态lib文件的时候,只需要配置好头文件.h的路径和库文件.lib的路径,自己的程序就可以正确加载这些第三方代码为自己所用。这是因为:

静态lib文件实际上就是任意个obj文件的集合,而obj文件就是cpp文件编译之后产生的一种文件,一个cpp文件编译之后只会产生一个obj文件而多个obj文件就可以连接生成lib文件。如果你工程里只有一个lib.h和lib.cpp,那么编译后产生的lib文件实际上就是lib.obj文件的一个集合,但是如果你工程里还有其他的很多个cpp文件,那么就会在编译之后生成许多obj文件,然后最终只链接生成一个lib文件

所以,静态lib文件实际上是包含了所有的导出声明和实现。你如果把这个lib文件链接到自己的程序之后,这个lib文件中的所有代码都会嵌入进来,哪怕你只用到了其中一部分,剩下没用到的也进了你的代码。这就不难想象会造成的后果了,虽然方便,但是如果大部分你都用不到,自然会导致你的库体积没有意义地变大,失去了使用动态库的灵活性,而且发布新的版本时必须要发布新的应用程序才行,而不是简单打个补丁就好。就是因为这种缺点,才会出现动态dll调用这种方式。

  1. 动态lib文件和dll文件

把这两个放在一起来说,是因为一个dll工程生成一个dll文件的时候,总是伴随着生成一个lib文件,这个lib文件其实是一个动态的lib,它的大小比静态lib要小很多,因为这个lib文件其实只是包含了一些函数索引信息,记录了dll中那些函数的入口和位置,dll中才是具体的函数实现。那么为什么有了dll,还要有一个lib呢?

这就是动态库链接的过程了,首先按前面所述方法,配置好动态lib库目录和动态dll目录,以及头文件的目录。然后在你的代码中include用到的头文件,代码完成之后有两个过程:(1)编译:这个过程只需要用到这里的动态lib文件【注:在静态lib的情况下,仍然只是在编译阶段用到lib文件,只不过静态lib文件包含了完整的实现,所以编译生成exe之后就可以直接用了而已】,然后和你的代码打包到一起。(2)运行:这个过程就需要用到dll文件了,上面打包好的东西里面,只是记录下了那些用到的函数的入口和具体位置,并没有真正的实现代码,所以在运行期间,就由那些入口找到正确的位于dll中的位置,然后直接执行那些函数就行了。

从上面过程中也可以看出一个很清楚的事实:dll其实就是exe,只不过它没有main函数,所以不能单独执行而已。事实上, 在实际的使用过程中我们也发现,**很多应用程序都并不是一个完整的单独可执行文件,它们被分割成一些单独的相对对立的动态链接库,只有在执行应用程序的时候,用到的dll才会被调用。这也就是为什么你经常打开某些程序,会出现“无法加载XXX.dll”**的原因了(微笑脸。

从vs的命令行中也能看出端倪:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值