C++生成动态连接库

文章目录

  • 一、静态连接与动态连接
  • 二、 动态链接库(DLL)的创建
  • 三、dll库的使用
  • 四、 动态链接链接库工作原理
  • 五、extern "C"

一、静态连接与动态连接

 静态库和动态库区别是库的加载时间不同。静态库:在链接阶段库将会与.o目标文件一起打包生成可执行文件,成为可执行文件的一部分,后续此库就可以消失了。也就是说在编译的最后一步(链接阶段),如果程序需要使用静态库,在这一步都会一起打包到可执行文件中。
优点:

  1. 使可执行文件依赖项少,已经被打包到可执行文件中了
  2. 编译阶段完成链接,执行期间代码装载速度快

缺点:

  1. 使可执行文件变大
  2. 若作为其他库的依赖库,将会造成多余的副本,因为必须与目标文件打包
  3. 升级不方便,升级必须重新编译

动态库:在编译阶段都不会有任何动作,只有在程序运行时才被加载,也就是动态库的链接是发生在程序运行时期的,它和可执行文件是分开的,只是可执行文件在运行的某个时期调用了它。
优点:

  1. 动态库可以实现进程之间资源共享,有一份就行。

  2. 升级程序简单,不需要重新编译。

缺点:

  1. 运行期间在加载,将会减慢代码执行速度。

  2. 增加程序的依赖项,必须跟着可执行文件一起。

二、 动态链接库(DLL)的创建

  1. VS2019新建动态连接库项目
    创建项目
    新项目
    可以看到新建的项目中自带framework.h, pch.h, dllmain.cpp, pch.cpp四个文件,这是需要新建自己的.h和.cpp文件。
  2. 分别创建用于声明和定义函数的头文件dlltest.h和源文件dlltest.cpp在这里插入图片描述
    在这里插入图片描述
     然后点击生成,编译器报错“……不是有效的win32程序“。
    在这里插入图片描述
    然后打开debug或者release文件夹,可以看到有.lib 和.dll文件。

三、dll库的使用

加载动态库有两种方式,分为隐式加载和显示加载:

隐式加载:所需文件:接口.h头文件,dll文件,lib文件。.h和.lib加载方式与静态加载完全一致。但.dll文件必须放在环境变量指定的目下。当然通常是与目标.exe文件放在一起。

显式加载:所需文件:dll文件。利用LoadLibrary()函数进行加载。

下面介绍一下常用的隐式加载的方法:
(1) 需要将创建的.dll文件以及.lib文件还有定义的.h头文件,拷贝至我们需要测试的新项目的目录下。
在这里插入图片描述

(2)将拷贝的头文件添加到空白项目中.
在这里插入图片描述

(3)在属性—链接器—输入—附加依赖项中添加我们拷贝过来的.lib文件。
在这里插入图片描述

(4)创建一个.cpp源文件开始进行动态库的调用,包含头文件,并且删掉头文件中的#include “pch.h”,随后直接可以调用封装的函数。
在这里插入图片描述

四、 动态链接链接库工作原理

  1. __declspec是Microsoft VC中专用的关键字,它配合着一些属性可以对标准C/C++进行扩充。__declspec关键字出现在声明的前面。
  2. __declspec(dllexport)声明导出函数、类、对象等供外部调用,省略.def文件(.def文件(模块定义文件)是包含一个或多个描述各种DLL属性的Module语句的文本文件,如果不提供__declspec(dllexport)导出DLL函数,则DLL需要提供.def文件)。
  3. __declspec(dllimport)用于Windows中,从别的动态库中声明导入函数、类、对象等供本动态库或exe文件使用。当使用DLL中的函数时,不需要显示地导入函数,编译器也可自动完成导入。__declspec(dllimport)可以确定函数是否存在于DLL中,这使得编译器可以生成跳过间接寻址级别的代码,而这些代码通常会出现在跨DLL边界的函数调用中。

五、extern “C”

void Swap(int a, int b);

C编译后,函数名变为 _Swap
C++编译后,因为有重载语法的原因,函数名变为 _Swap_int_int

同一个函数经过C和C++编译后,函数名不同。extern “C” 让C++以C的命名风格编译代码。

上一篇:Linux 常用命令


下一篇:数据库hang住分析处理