前言:C以及C++的动态链接库和静态链接库,说起来很简单,但是实际上在创建的过程中有很多的坑,本人也是一路踩了很多坑,查了很多资料,下决定写一篇完整的文章来详细解释使用VS创建C++动态链接库的完整流程。本文的开发环境是VS 2017。
一、Windows的动态链接库简介
DLL即动态链接库(Dynamic-Link Library)的缩写,相当于Linux下的共享对象。Windows系统中大量采用DLL机制,甚至内核的结构很大程度依赖于DLL机制。Windows下的DLL文件和EXE文件实际上是一个概念,都是PE格式的二进制文件。
1.1 Windows下面的动态链接库与Linux下面的动态链接库的区别
(1)文件后缀不同
Linux动态库的后缀是 .so 文件,而window则是 .dll 文件
(2)文件格式不同
(a)Linux下是ELF格式,即Executable and Linkable Format
在ELF之下,共享库中所有的全局函数和变量在默认情况下都可以被其它模块使用,即ELF默认导出所有的全局符号。
(b)Windows下面是PE格式的文件,即Portable Executable Format
DLL本质上也是PE文件,DLL需要显示地“告诉”编译器需要导出某个符号,否则编译器默认所有的符号都不导出。
(c)动态链接库的文件个数不一样
Linux的动态链接库就只有一个 .so 文件,还有与之对应的头文件,而在Windows下面的动态库有两个文件,
一个是引入库(.LIB)文件,
一个是动态库(.DLL)文件,
需要的头文件(.h)文件
(1)引入库文件包含被DLL导出的函数的名称和位置,对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。
(2)DLL文件包含实际的函数和数据,应用程序使用LIB文件链接到所需要使用的DLL文件,库中的函数和数据并不复制到可执行文件中,因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址,这样当一个或多个应用程序运行是再把程序代码和被调用的函数代码链接起来,从而节省了内存资源。
总结:从上面的说明可以看出,Windows下面所创建的动态链接库DLL和.LIB文件必须随应用程序一起发行,否则应用程序将会产生错误。一般的动态库程序有lib文件和dll文件,lib文件是编译时期连接到应用程序中的,而dll文件才是运行时才会被调用的。
1.2 比如有下面的代码
头文件myMath.h
//myMath.h
namespace mycal
{
int add(int a, int b);
int sub(int a, int b);
}
#pragma once
实现代码 myMath.cpp
//myMath.cpp
#include "myMath.h"
int mycal::add(int x, int y)
{
return x + y;
}
int mycal::sub(int x, int y)
{
return x - y;
}
在Linux下,编译成动态链接库之后,会得到一个 xxx.so 文件,现在只要引入头文件,包含动态库路径,就可以正常使用了,但是上面的代码同样在Windows下面,使用VS2017编译成动态链接库之后,的确不会报错,只会的到一个 xxx.dll 文件,(不是还有一个对应的 xxx.lib文