python lib文件,.dll和.lib

  python lib文件,.dll和.lib

  1.静态链接库与库导入库和动态链接库dll的关系

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

  请先叹气。怎么努力还是被抛弃了:悲剧的人生莫过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库的生成方法,请写一个简单的静态库,自己使用。

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

  Item”,然后选择源文件,然后命名为qtwidgetsapplication2.cpp当然是自己取名字了。然后在qtwidgetsapplication2.cpp文件的开头包含以下头文件,因为在源文件中函数的声明都会放在头文件。而且因为创建的是静态lib库,所以最终的函数声明需要放在头文件中供别人使用的。其他的在获取静态lib库的时候必须有相应的头文件。因此,函数声明和函数定义分别分为头文件和源文件。源(.cpp)文件中包含头文件的代码如下:

  # include qtwidgetapplication 2 . h 如果您定义了自己的名称,那么这个包含的头文件必须是您定义的头文件。名称并不重要,但是当包含头文件时,头文件与源文件相关联。头文件和源文件的名称也可以不同。这些都不重要。

  我们在头文件中编写一个函数声明,如下所示:

  void show(char * szMsg);此代码表示声明。因为这个函数涉及标准输出,所以我们在头文件中包含了一个标准的输入和输出头文件。只要包含在头文件中,就可以使用源文件。当然,您也可以在源文件中包含标准的I/O头文件。无论你想要什么。反正你要在头文件里用,放在头文件里包含就行了,省点事。

  好了,头文件到此为止。头文件qtwidgetsapplication2.h的代码如下:

  # include stdio . hvoid 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:\ documents \ Qt study \ qtwidgetapplication 2 \ x64 \ debug \ qtwidgetapplication 2 . lib,你看到了lib文件,什么意思,说明lib文件生成成功。如果失败了,就看不到这个了。

  然后转到项目文件夹,查看lib文件。我们直接右键点击“解决方法资源管理器”上方的项目“解决方案XXX(1个项目)”,点击“在文件资源管理器中打开文件夹(X)”,从而快速打开项目文件夹。

  如果你的VS界面上的工具栏显示Debug,那么就是调试模式,生成的lib文件在Debug文件夹里。如果它处于Release模式,则生成的文件位于Release文件夹中。调试设置在我的工具栏的这个位置,如下图所示:

  这个可以自由选择,如果在编码阶段,最好是Debug方便调试,如果是最终发布,就调成发布版的Release版的话。

  打开文件夹后,您会看到以下内容:

  转到“Debug”文件夹,看看lib文件是否真的出现了。看下图:

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

  最后,你可以把头文件(。h)在源文件和这个lib文件中的其他项目中使用它。如果最终给了别人,请用发布版生成,给别人。

  另外,你可以选择。dll,lib和。exe中的项目属性根据自己的需要生成。

  三。如何使用静态lib库?开源库第三方库如何静态链接?如果你写了一个MFC程序,当程序被别人运行时,总会提示MFC dll不存在,这是一个很麻烦的问题。如果我们想要一个静态链接,我们实际上想要引入静态lib库。这样的话,最后一个环节之后,就是打包到exe了。引入静态库是这里的关键。其他一切与普通程序相同。添加头文件和包含头文件,其他没什么不同。不同的是没有提供函数的定义。那么静态lib的函数定义就在这个文件里,所以我们引入之后,就完成了函数定义。静态lib库的引入最终完成了代码到exe的打包。

  在第二部分中,我们学习了如何创建我们自己的静态库。通过自己的实践,对别人的静态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导入库是没有代码的,只是对dll的说明。所以,第一步,如果你不知道,一直在找怎么用dll静态链接,你一辈子都解决不了这个问题。

  如果是开源库或者第三方,一般会提供两种方式,或者想要静态链接,下载静态lib版本。有了事情就好办了。

  好的,我们下面来看看如何静态链接第三方库,或者说是如何使用静态lib库吧。

  你得先有一个建立的项目,然后,把你得到的lib文件和头文件放到源文件里(。cpp)文件夹,即和.c或.cpp文件放在一起

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

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

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

  1m.obj:错误LNK2001:未解析的外部符号 void __cdecl show(char *)(?Show @ @ yax pad @ z)1C:\ Users \ WDX \ Documents \ Visual Studio 2015 \ Projects \ Console _ 1 \ Release \ Console _ 1 . exe:致命错误LNK1120: 1未解析的外部命令这个“未解析的外部命令”和“致命错误LNK1120”这里的提示是show函数无法解析。虽然声明了后置函数,但是找不到函数定义。看到这个错误,你应该知道你的函数没有写定义。因为这是一个静态lib库,所以你应该认为这就是不引入静态lib库的原因。

  是的,我们想要一个静态链接,实际上就是引入一个静态的lib库。这种情况下,最后一个链接后,会打包成exe。引入静态库是这里的关键。其他一切与普通程序相同。添加头文件和包含头文件,没有其他区别。不同的是没有提供函数的定义。那么静态lib的函数定义就在这个文件里,所以我们引入之后,就完成了函数定义。静态lib库的引入最终完成了代码到exe的打包。

  好吧。先用VS的项目设置来介绍一下。依次点击以下菜单:项目-"XXX项目"弹出项目属性页,然后找到配置属性-链接器-输入-附加依赖项,如下图所示:

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

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

  那就确定一下。我们再按一下VS菜单“生成”——“重新生成解决方案”。成功!如下图所示:

  这是最后一个,如果在生成lib的项目中写了main函数,情况会如何?我们进行了实验,然后将生成的lib引入到再生解决方案中,出现了以下错误:

  1m.obj:错误LNK2005: _main已定义1c:\ users \ wdx \ documents \ visual studio 2015 \ projects \ Console _ 1 \ release \ Console _ 1 . exe:致命错误LNK1169:找到一个或多个具有多个定义的符号。错误消息_main已定义,“发现一个或多个具有多个定义的符号”,表明我们当前项目中的main和static lib库之间存在冲突。这也证明了main函数不能像前面提到的那样写在静态lib库中。

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

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: