dll和lib的区别和使用

简介

lib(静态库,library):lib分为两种,一种是通常意义上的静态库,里面是函数实现代码;还有一种是导出库,配合dll使用,实现隐式调用。两者都是用于静态链接,在生成目标模块后,lib文件就没有用了。
dll(动态库,dynamic link library):dll用于动态编译,调用dll的程序本身只有导出函数的声明,而将实现过程放到dll中,这样dll就可以提供给多个程序使用,大大减少了程序体积,是实现代码复用的重要手段。编译的时候不需要dll,运行时却必不可少。
总之:lib相当于代替cpp文件编译,而dll相当于把cpp文件放到程序外面。

libdll
文件后缀.lib.dll
类型静态库动态链接库
何时依赖编译时依赖运行时依赖
使用方式程序编译时链接到目标模块中显示调用或隐式调用,要求运行时能找到

生成

生成lib的目的是为了将.h文件和.lib文件提供给其他的项目使用,如一些第三方库;
生成dll则是提供一些导出函数让其它项目显示调用(只需要dll文件),或者隐式调用(除了dll外,副产品.h文件和.lib文件仍然通过静态链接的方式提供dll导出函数的信息)。

在VS2019中,新建项目的时候可以选择项目类型,dll或者lib。
新建项目选择dll

一个普通的exe项目可以较为方面的改为lib或dll配置。需要在项目属性配置项目生成类型。编译后即可在输入目录中找到对应的lib或dll文件(dll需要改代码,声明函数)。

修改项目生成配置

在windows下使用 _declspec(dllexport)修饰需要导出的函数,如下所示,其中extern "C"保证c++环境下编译后的函数名为C语言风格,更适合显示调用。

//MyDll.cpp
extern "C" __declspec(dllexport) void DllFunction() //declspec前是两个下划线
{
std::cout << "Call dll function.\n";
}

使用

lib的使用

lib是在编译用来链接的,所以使用lib就需要配置好编译环境,比如一般第三方库都是提供了include目录和lib库文件。在VS2019中,则需要在项目属性中配置3个相关变量。

  1. 包含目录(或者附加包含目录):.h文件所在的目录
  2. lib的库目录(或者附加库目录):lib所在的目录
  3. 附加依赖项:需要依赖的lib文件名,可以使用#pragma comment (lib ,“**.lib”))代替

dll的使用:

dll的使用相对复杂一点,分为两种,显示调用和隐式调用。
首先需要知道程序是在哪里找到dll文件的,在Windows下dll的搜索顺序为:
1..exe文件的目录
2.进程的当前工作目录
3.Windows系统目录
4.Path环境变量中的目录
所以需要将dll拷贝到程序的相应目录中,或者为dll目录配置环境变量,让程序运行时可以找到这个dll文件。

显示调用(只运行时需要dll文件):

以windows下为例,主要通过loadLibray()和GetProcAddress()获得dll导出函数(省去了合法性检查):

//#include<windows.h>
	typedef void(*DllFunctionType)();//dll导出函数签名
	HINSTANCE myDllInstance = LoadLibrary(L"MyDll.dll"); //加载dll,L表示unicode字符串
	DllFunctionType dllFunction = (DllFunctionType)GetProcAddress(myDllInstance, "DllFunction");
	dllFunction();//调用dll函数
	FreeLibrary(myDllInstance);//释放dll

隐式调用(编译时需要h文件和lib文件,运行时需要dll文件):

这种方式与普通lib库的使用并无区别,只是h文件中变成了导入函数的声明,在windows下用_declspec(dllimport)修饰。

//MyDll.h
	_declspec(dllimport) void DllFunction();
//#include <MyDll.h>
	DllFunction(); //直接调用即可

版权声明:本文为weixin_43844254原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。