首页 > 编程知识 正文

python的lib库,lib文件和dll文件的区别

时间:2023-05-04 09:25:58 阅读:164410 作者:1525

一.静态链接lib库和lib导入库和动态链接库dll的关系

您应该经常听到“lib静态库”和“导入lib库”这样的词吧。 但是,lib是怎么来的,怎么用的,我们很多人还不知道哦。 我也是专门研究学习才发现的。 所以在这里详细说说,分享给大家。 如果你想详细了解完整编译链接的过程,可以看看《C++零基础入门课程》的第三章。

请先感叹一下。怎么努力还是被抛弃了:悲剧的人生莫过Lib库了!!如果不知道的话,仔细阅读下面的介绍就明白了。

lib库实际上有静态链接lib库或者叫做静态lib库动态链接库dll库的lib导入库或称为lib导入库两种。 因为这两个库不同,所以很多人不能明确区分,容易混淆。 在这里我会解释清楚。 你不会再混乱了。

第一种是静态lib包含所有的代码实现,是编译源代码文件. c或. cpp文件生成的,这个lib库是编译文本格式源代码的二进制格式代码

第二种就是lib导入库,该库只是dll文件中所有函数的地址说明。

从两个库的说明中可以看出,静态lib文件里是包含了所有的代码的,所以导入后,只要使用链接器链接生成exe文件,exe文件就可以直接使用exe内部的代码。 链接lib库的过程相当于lib库中所有二进制文件的代码复制到exe文件。 所以,链接后,用静态lib库文件就不需要了最后,用只要exe就可以了。 这个lib链接后,已经失去了价值。 exe文件已经有副本了,不需要依赖它。 嘿嘿,exe文件好像有点绝情哦,哈哈。 但是,每次编译链接并生成exe时,都需要这个静态lib库。 也就是说,最后你要给别人的是给一个exe就行了,就不必将lib也给别人代码的时候,要写调用lib库里的函数。 我们通过提供的头文件来知道lib静态库里都有些什么函数

这个lib导入库可以说明dll的内部结构,就像dll的内部很熟悉一样。 我们通过在lib上导入库,可以很容易地调用dll中的函数。 当我们在程序中使用dll时,我们导入了lib导入库,然后将dll放入项目中,我们就可以直接使用dll的代码,就像我们写的cpp源代码文件一样。 所以很方便。 这也是lib导入库存在的原因。

使用dll还可以直接使用API函数来获取dll内部函数的地址,并将函数类型转换为正确的函数类型。 这些函数类型声明就在提供的头文件中了。 头文件和我们自己写的头文件一样。 这个过程非常麻烦。 这有上面的lib导入库所在的空间。

如果要在API函数中直接动态使用dll内部函数,则不需要lib导入库。 也就是说,使用lib引入温暖彩虹和通过API直接使用dll中的函数有两种方法。 所以二选一就可以了。

同样,lib导入库编译链接后,也会将dll中的函数地址结构等信息复制到exe中。 所以,在最后生成程序后,lib导入了库,经历了与静态lib相同的命运,它被抛弃了。 呃,现实已经很残酷了。 在电脑里,更残酷。

对于静态lib的生成和使用,以及dll和lib导入库的生成和使用,则在下一节介绍。

2、lib静态库是如何生成的? 如何生成自己的lib静态库?

我们经常使用别人的静态lib库,他们是怎么来的呢? 要清楚地了解静态lib库的生成方法,请自己编写一个简单的静态库,自己使用吧。 生成后,你变成了将源文件中的头文件和这个lib文件放在其他项目里就可以使用。 如果你最终生成给别人,请使用Release版本给别人哦。

前一节说明了这些概念之间的差异和关系。 也可以参考《C++语言零基础入门教程:3.3 链接代码是什么,为什么需要链接,如何链接代码》,获得更丰富的技术介绍。

我们经常使用别人的静态lib库,他们是怎么来的呢? 要清楚地了解静态lib库的生成方法,请自己编写一个简单的静态库,自己使用吧。

创建控制台程序项目。 创建控制台项目。 所有的VS都是一样的。 在中,添加头文件qtwidgetsapplication2.h。 在VS中,只需右键单击“解决方案资源管理器”下项目的“头文件”,添加“新建条目”,选择头文件,然后将其命名为test.h。 然后,右键单击“源文件”,选择“新建”

项”,然后选择源文件,然后命名为qtwidgetsapplication2.cpp。当然这个名字自己随便取。然后在qtwidgetsapplication2.cpp文件开头包含以下头文件,因为源文件中函数的声明都会放在头文件中。而且,因为是创建lib静态库,最后的函数声明需要放在头文件中供别人使用的。别人拿到静态lib库时一定有一个对应的头文件。所以,函数声明和函数定义分别分到头文件和源文件中。在源(.cpp)文件中包含头文件的代码如下:

#include "qtwidgetsapplication2.h"

如果你自己定义名字,那么这个包含的头文件,一定要是你定义的头文件。名字无关紧要,不过在包含头文件才是将头文件和源文件关联起来的时候。头文件和源文件名称也可以不一样。这些都无所谓的。
我们在头文件写一个函数的声明如下:

void show(char* szMsg);

这一句代码就表示了声明,因为这个函数会涉及到标准输出,所以我们在头文件里包含一个标准输入输出头文件。只要在头文件中包含了,源文件也就可以使用了。当然,你也可以在源文件中包含标准输入输出头文件。随你了,反正如果在头文件中也要用的上的,就直接放在头文件中包含,这样就省事些。
好了,头文件就这么多,头文件qtwidgetsapplication2.h的代码如下:

#include <stdio.h>void show(char* szMsg);

在源文件qtwidgetsapplication2.cpp中,我们写show函数的定义,源文件qtwidgetsapplication2.cpp的代码如下:

#include "test.h"void show(char* szMsg){ printf(szMsg);}

就这么多,代码写完了。不对呀,这个怎么和C程序一样呢??是的,好戏才刚刚开始。问题不在于代码怎么写,代码和正常一样的写,不要以为生成静态lib库有什么了不起的哦。

  
那么生成静态lib库,关键点在于生成的目标文件的格式了。我们要在项目属性里设置下。
单击VS的主菜单“项目”,然后单击“XXX属性(P)...”,在弹出的属性页中,我们单击左边的“配置属性”下的“常规”,然后在右边可以看到一系列可以设置的值,如下图所示:

 从图中可以看到,点击“项目默认值”的“配置类型”右边的下拉框,然后可以看到有好几个选项:生成文件、应用程序(.exe)(默认的)、动态库(.dll)、静态库(.lib)和实用工具。那么此时我们选择“静态库(lib)”,确定即可。


好了,就这样,我们再来点击VS菜单的“重新生成解决方案”,然后看底下的“输出”窗口,看到如下提示:


提示说全部重新生成:成功1个,失败0个,跳过0个。表示没有任何错误。上面提示D:documentsqtstudyQtWidgetsApplication2x64DebugQtWidgetsApplication2.lib,你看到了lib文件,你说代表什么,这说明生成lib文件成功了。如果失败,是看不到这个的。
然后到项目文件夹看看lib文件。我们直接在“解决方法资源管理器”最顶部“解决方案XXX(1个项目)”项右击,单击“在文件资源管理器中打开文件夹(X)”,这样就快速打开了项目文件夹哦。
如果你的VS界面上的工具栏显示的是Debug,那么就是调试模式,那么生成的lib文件在Debug文件夹下。如果是Release模式,则生成的在Release文件夹下。我的工具栏这个位置设置的是Debug,如下图所示:

 

这个可以自由选择,如果在编码阶段,最好是Debug,方便调试,如果最终发布,就调成发布版的Release版
打开文件夹后,看到是这样的:


去“Debug”文件夹看看,是不是真的出现了lib文件呢?看下图:

 
是不是挺简单的。自己也动手试试吧。不过最后要交待几句。
因为是静态库,所以你这个库是生成给别人用的,或者是在其他程序使用的,那么就不需要你写main函数了。实际上,这个库就是一个工具库,只需要一些函数就行了。在头文件中有函数声明,在代码中有函数的定义,就可以了。不要在自己的静态库中写main函数哦,不然别人在使用你的静态库可能会出问题的,因为会有多个main函数。一般是没有人这么做的,或者说熟手就不会了,但是新手有时候不清楚就真的带上了。


那么最后你将源文件中的头文件(.h)和这个lib文件放在其他项目里就可以使用了。如果你最终给别人,请使用Release版本生成后给别人哦。

另外在项目属性中可选.dll和.lib和.exe,根据自己的需求进行生成

 

三、如何使用静态lib库?如何静态链接开源库第三方库?

如果写过MFC程序,程序给别人运行的时候,总是提示什么MFC的dll不存在,这个是一个很麻烦的问题。我们要静态链接,其实就是要引入静态lib库,这样的话,最终链接后,就打包到exe了。引入静态lib就是这里的关键哦。其他的都和普通的程序一 样。添加头文件和包含头文件,没有其他不一样的地方。不一样的就是没有提供函数的定义。那么静态lib的函数定义就在这个文件中,所以我们引入后,就补全了函数定义了。而这个引入静态lib库,最终也完成了将代码打包到了exe。 

在第二节中,我们学会了如何创建自己的静态lib库了。通过自己的实践,我们就很清楚人家的静态lib库是如何来的了。那么我们接下来的任务就是使用静态lib库了。
先来说说我们经常疑问的问题就是如何静态链接一个第三方库。那么这个问题,是因为对此一无所知导致的。只要看了这一系列的文章,这都不是问题。因为之前我也这么疑问过。
那么我们为什么要静态链接呢?我们写过MFC程序,程序给别人运行的时候,总是提示什么MFC的dll不存在,这个是一个很麻烦的问题。我们也懒得去一个个找到这个dll放在exe文件一起,这样发给别人真心麻烦。还有,我们总不喜欢一大堆东西去找一个exe运行,很多人甜美的盼望哦,根本就不知 道去双击exe运行。那你只给exe的时候,他看上去还有选择吗?那肯定是直接双击exe。对于甜美的盼望这个,都不是关键。
MFC程序项目默认的是共享DLL方式,也就是动态链接的。动态链接意味着链接的时候并没有把MFC库打包到exe中,所以,当运行程序的电脑没有MFC库的时候,就缺少了MFC库。
对于程序文件大小不限制的情况下,尽可能使用静态链接。这样分享软件时候,就方便了。只不过就是静态链接的程序会大一点点而已。
然而,我们很多时候写的并不是MFC程序,那么此时要静态链接,如何做?比如我们在使用opencv时,如果使用的是静态链接,那就不用带上一堆dll 了。那些dll那么多看上去都恐怖。然而,我们知道要静态链接,但是很多人也不知道如何静态链接,甚至连需要拿什么来链接都不清楚。是IDE设置还是需要准备特定的文件呢?

有时候我们只得到了dll文件和头文件还有与dll对应的lib导入库文件,这个时候是没有办法静态链接的哦。这个关键在于需要有静态lib,这个静态 lib库包含了所有的二进制代码,才能链接。lib导入库是没有代码的,只是对dll的说明。所以,第一步如果你不清楚,一直在找如何用dll静态链接, 一辈子都搞不定这个问题。
如果是开源库或第三方,一般是提供两种方式的,或者你要静态链接,就下载静态lib版本。有了东西才好办事。
好了,我们下面来看看如何静态链接第三方库,或者说是如何使用静态lib库吧。
你先要有一个建立好的项目,然后,将你得到的lib文件和头文件放在你项目的源文件(.cpp)文件夹下,也就是和.c或.cpp文件放在一起

 好了,文件准备好后, 我们在VS中的“解决方案资源管理器”的“头文件”项右击,添加“现有项”,然后添加刚才得到的第三方库的头文件。


我们这里就添加生成的静态lib库的头文件。然后在我们自己的源文件main.cpp中写好main函数,在开头包含qtwidgetsapplication2.h,然后在main调用qtwidgetsapplication2头文件声明的函数show。我们使用静态lib库的项目是生成exe哦。如下图所示:

 
然后我们直接按F5调试运行,这样会自动编译链接运行。然后发现了问题,提示:

1>m.obj : error LNK2001: 无法解析的外部符号 "void __cdecl show(char *)" (?show@@YAXPAD@Z)1>C:Userswdxdocumentsvisual studio 2015ProjectsConsole_1ReleaseConsole_1.exe : fatal error LNK1120: 1 个无法解析的外部命令

这个“无法解析的外部命令”和“fatal error LNK1120”想必是大家经常碰见的吧。这里提示的是show函数无法解析。虽然后函数声明,但是却找不到函数定义在哪里。看到这个错误,你应该知道你 的函数没有写定义。因为这个是静态lib库的,所以,你就应该想到,这个是没有引入静态lib库的原因哦。
是的,我们要静态链接,其实就是要引入静态lib库,这样的话,最终链接后,就打包到exe了。引入静态lib就是这里的关键哦。其他的都和普通的程序一 样。添加头文件和包含头文件,没有其他不一样的地方。不一样的就是没有提供函数的定义。那么静态lib的函数定义就在这个文件中,所以我们引入后,就补全 了函数定义了。而这个引入静态lib库,最终也完成了将代码打包到了exe。
好了。我们先用VS的项目设置来引入。依次点击下面的菜单:“项目” -> “XXX项目”,弹出项目属性页,然后找到“配置属性”-> "链接器" -> “输入” -> “附加依赖项”,如下图所示:


从图中可以看到,这里面已经有了一些静态lib库了。然后单击一下“附加依赖项”选中后就出现了下拉箭头,再点击右边的下拉箭头,然后点击编辑,如下图所示:


然后弹出编辑框,输入我们放在项目源码文件夹的lib文件名,如下图所示:


然后确定即可。我们再按VS的菜单“生成”->“重新生成解决方方案”,成功!如下图所示:

这里要一下上一篇提到的,如果在生成lib的项目中写了main函数,情况会如何?我们实验了一下,然后将生成的lib引入重新生成解决方案,出现了如下的错误:

1>m.obj : error LNK2005: _main 已经在 Console_1.lib(test.obj) 中定义1>C:Userswdxdocumentsvisual studio 2015ProjectsConsole_1ReleaseConsole_1.exe : fatal error LNK1169: 找到一个或多个多重定义的符号

错误提示_main已经定义,“找到一个或多个多重定义的符号”,说明我们现在的项目中的main和静态lib库中的冲突了。这也证明了上一节中说的,不能在静态lib库中写main函数咯。

参考:https://mp.weixin.qq.com/s/VcicslMbWtuJ6YUJfBPxiw

 

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。