C++ 静态和动态链接库

注意:本菜刚接触,勿看!!!误导概不负责!!!!

1:对什么是静态库什么是动态库的理解

-:静态库是给你一份代码,然后在你配置好静态库的情况下,在运行程序前的编译时期编译器会将静态库中的代码拷贝到程序的内存中...和include干的事情一样,只是单纯地把内容粘贴复制

-:动态库是告诉你哪有一份代码[当然,你要自动配置让链接器知道代码在哪个文件中],然后通过某种方式获取代码的内存地址,通过这个内存地址去调用动态库

-:优缺点

        ·:静态库的性能好,动态库的性能相对较差

        ·:如果多个程序使用同一个lib文件,那么内存中会有多份相同的代码,动态库由于是共享机制,所以不好有这个困扰

2:怎么配置静态库和动态库

这里我是在网上下载了GLFW库

Download | GLFW

[注意,下载32位的还是64位的不是取决与你的操作系统,而是取决你的解决方案环境,如果是WIN32那么就下载32位的]

下载后会有以下文件:

C++ 静态和动态链接库_第1张图片

 

其中我们只需要关心include文件和lib-vc文件即可,注意选择离你编译器版本最近的lib-vc文件;

一般我将这两个文件放入到我的解决方案中:

C++ 静态和动态链接库_第2张图片

 注意,我这里用了一个Depend文件夹将这两个文件整合了;

然后将相对路径[绝对路径也行]加到附加包含目录中,这样编译器就可以找到include文件了:

C++ 静态和动态链接库_第3张图片

//静态库 

        现在我们试一下写一个用到GLFM中的函数的解决方案:

C++ 静态和动态链接库_第4张图片

         运行并报错:

         但是当我们写代码时,编译器并没有给我错误提示,因为我们只有glfwInit函数的函数声明,在glfw3.h文件中;

我们查看函数声明:

C++ 静态和动态链接库_第5张图片

         看到只有函数声明,并没有函数定义;

        那么接下来就是让链接器找到glfw.lib文件了:

        我们在属性中配置这两个选项:

C++ 静态和动态链接库_第6张图片

 C++ 静态和动态链接库_第7张图片

         第二个是告诉连接器,我们应该去找一个叫glfw3.lib的静态库,如果细心的话,会发现,这个glfw3.lib就在lib-vc文件中,然后第一个是添加了一个搜索目录,我们会在这个目录中搜索我们需要的依赖;

接着,我们运行程序:

C++ 静态和动态链接库_第8张图片

no problem!

 上面就是静态库的配置方法,总结一下:

        -:在c++常规中包含include文件,这个文件提供函数声明;

        -:在链接输入中包含静态库文件【当然我们可以在里面填写绝对路径,这样就可以不在链接常规中包含搜索目录了,但可能一个搜索目录中含有多个我们想要的静态库,所以都是在链接常规中包含搜索目录,然后在链接输入中包含库名】,这里会提供函数定义;

动态库:

先看动态库文件,我们下载的文件有两个相关的一个是动态库,一个是静态库:

C++ 静态和动态链接库_第9张图片

        首先动态库文件在存储的是函数实体,然后静态库里存储的是动态库的一些指针,这两个文件是相依相存的,我们将静态库中的一些指针插入到exe文件中,然后检索这些指针来调用动态库里的函数或者另外的一些类或者数据等等;

        然后我们需要告诉编译器,我们要将glfw3dll.lib文件给加载到我们的exe文件当中;

        这说明我们的exe文件与dll文件是不相关的,当我们的exe文件运行到一个依赖dll文件的时候,链接器会通过lib文件中的指针检索到相应的代码,然后将其加载下来[如果没被加载过的话];

        注意,对于include"GLFM/glfw3.h"这个包含语句是不变的,因为静态和动态库不同在于提供函数定义的地方不同,对于函数声明还是一样的;

        先在链接输入中写入glfw3dll.lib,其他不变: 

        C++ 静态和动态链接库_第10张图片

启动程序并报错:

C++ 静态和动态链接库_第11张图片

 这个时候我们只是有了指针,并没有告诉链接器函数定义在哪;

在链接器找dll文件的过程中会依次遍历以下路径:

1. 包含EXE文件的目录,

2. 进程的当前工作目录,

3. Windows系统目录,

4. Windows目录,

5. 列在Path环境变量中的一系列目录。

然后我们只需要在1中加入dll文件即可,即我们要保证以上路径中有我们想要的dll文件,如图:

C++ 静态和动态链接库_第12张图片

然后就可以成功运行了!

 几个有趣的点:

我们打开glfw3.h然后我们会看见每个函数定义前都有GLFWAPI的宏定义:

然后我们看看GLFWAPI是怎样定义的:

C++ 静态和动态链接库_第13张图片

 吼!牛逼,上面的截图是我配置好dll的,但我们发现__declspec(dllimport),被禁用了,取而代之,GLFWAPI是空,这是为什么?为什么我们不需要dllimport也能从dll文件中找到对应的内存呢?

C++ 静态和动态链接库_第14张图片

 

这是因为我们已经加载了glfw3dll.lib文件,里面已经有指针了,所以不需要import;

注意:如果我们不包含glfw3dll.lib文件,并设置GLFW_DLL宏定义,即打开__declspec,我们仍然得不到我们想要的,至于为什么,本菜不知...

你可能感兴趣的:(1024程序员节)