静态链接库(*.lib)

如果在程序中使用静态链接库,那么链接器在链接的过程中会将**.obj文件.lib文件组织成可执行exe文件**,也就是将.lib中的代码链接到可执行文件中,因此生成的exe文件比较大。 程序运行时,将全部数据加载到内存。如果程序体积较大,功能较为复杂,那么加载到内存中的时间就会比较长,最直接的一个例子就是双击打开一个软件,要很久才能看到界面。这是静态链接库的一个弊端。 但程序在发行时不需要提供库文件。

静态库优点总结

  1. 代码装载速度快,执行速度略比动态链接库快
  2. 程序在发行时不需要提供库文件,不存在兼容性问题

静态库缺点总结

  1. 使用静态链接生成的可执行文件体积较大,包含相同的公共代码,造成浪费
  2. 程序可扩展性差
动态链接库(*.dll)

动态链接库又分为两种加载方式:隐式加载显式加载

隐式加载

隐式加载,也称载入时加载,是程序载入内存时加载所需的dll文件,且该dll随主进程始终占用内存。在编码时需要使用#pragma comment(lib,"myDll.lib")获得所需函数的入口。注意该.lib与静态链接库的.lib文件不同,静态链接库的.lib中包含了所需函数的代码,动态链接库的.lib仅指示函数在dll文件中的入口

隐式加载也会有静态链接库的问题,如果程序稍大,加载时间就会过长

显式加载

显式加载,也称运行时加载,是在程序运行过程中加载,不需要该dll时则将其释放。在需要时使用LoadLibrary加载,不需要时使用FreeLibrary释放。如果在LoadLibrary时该dll已经在内存,则只需将其引用计数加1,如果其引用计数减为0则移出内存。

使用动态链接库的程序在发行时需要提供dll文件。在编译时,如果使用隐式链接则需要提供**.lib文件**,生成可执行文件后则不再需要该.lib。如果使用显式链接,在编译时不需提供.lib文件。

显式加载将较大的程序分开加载的,程序运行时只需要将主程序载入内存,软件打开速度快,用户体验好。

动态库优点总结

  1. 更加节省内存并减少页面交换
  2. dll文件与exe文件独立,只要输出接口不变(即名称、参数、返回值类型和调用约定不变),更换dll文件不会对exe文件造成任何影响,因而极大地提高了可维护性和可扩展性
  3. 不同编程语言编写的程序只要按照函数调用约定就可以调用同一个dll函数
  4. 适用于大规模的软件开发,使开发过程独立、耦合度小,便于不同开发者和开发组织之间进行开发和测试

动态库缺点总结

  1. 使用动态链接库的应用程序不是自完备的,它依赖的dll模块也要存在,如果使用载入时加载(隐式加载),程序启动时发现dll不存在,系统将终止程序并给出错误信息。而使用运行时加载(显式加载),系统不会终止,但由于dll中的导出函数不可用,程序会加载失败
  2. 性能损失
  3. 存在兼容性问题

动态链接库使用示例

dll源码:

#include <Windows.h>  
#include <stdio.h>  
 
extern "C" {
	_declspec(dllexport) int testAdd(int x, int y)
	{
		return x + y;
	}
}

使用隐式链接:

#include"stdafx.h"
using namespace std;
 
#pragma comment(lib,"myDll.lib")//加载动态库
 
extern "C" {
	_declspec(dllimport) int testAdd(int x, int y);
}
int   main(int   argc, TCHAR  *argv[]) {
	_tprintf(_T("sum is %d\n"), testAdd(2,5));
	system("pause");
	return 0;
}

使用显示链接:

#include"stdafx.h"
using namespace std;
 
int   main(int   argc, TCHAR  *argv[]) 
{
	HINSTANCE h = LoadLibrary(_T("myDLL"));//加载动态库
	GetErrorMessage(GetLastError(), 0);
	int(*pAdd)(int, int) = NULL;
	pAdd = (int(__cdecl *)(int, int))(GetProcAddress(h, "testAdd"));
	GetErrorMessage(GetLastError(), 0);
	if (pAdd == NULL) {
		FreeLibrary(h);
		return 0;
	}
	int sum = pAdd(239, 23);
	_tprintf(_T("sum is %d\n"), sum);
	FreeLibrary(h);
	system("pause");
	return 0;
}

参考:

https://blog.csdn.net/Hilavergil/article/details/78544424

https://www.nowcoder.com/questionTerminal/8b1ebbb150494810881bd04e190e2cf5?source=relative

http://c.biancheng.net/cpp/html/2754.html