静态链接库和动态链接库

一、前言

1、代码复用是提高软件开发效率的重要途径。
2、一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用。小到一个函数、一种数据类型、一个类,大到一种类、一个模块、库。
3、复用从方式上又分为“源码级别”的“白盒复用”,和“二进制级别”库的“黑盒复用”。
4、“白盒复用”的缺点大致有4点:暴露了源代码;多份拷贝,造成存储浪费;容易与程序员的“普通”代码发生命名冲突;更新功能模块比较困难,不利于问题的模块化实现。如ATL、MFC用程序框架都以源代码的形式发布的“白盒复用”。
5、“黑盒复用”一定程度上隐藏了源代码,缓解代码耦合现象。分为静态库和动态链接库。

二、静态链接库和动态链接库

1、区别:
静态链接库和动态链接库的相同点是它们都实现了代码的共享,不同点是静态链接库.ib文件中的代码被包含在调用的.exe文件中(运行时无需该lib文件),该.lib文件中不能再包含其他动态链接库或者静态链接库了。而动态链接库.dll文件可以被调用的.exe动态地“引用”和“卸载”,该.dll文件中可以包含其他动态链接库或者静态链接库。

2、制作方法
静态链接库和动态链接库_第1张图片
定义静态库的函数

#include "pch.h"
#include "framework.h"

// TODO: 这是一个库函数示例
void fnStaticLibrary()
{
}

定义动态链接库(DLL)

#include 
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

定义具有导出项的(DLL)动态链接库
在定义动态链接库基础上增加以下代码

说明:导出项的(DLL)动态链接库会生成lib文件

//此 DLL 中的所有文件都是用命令行上定义的 DYNAMICLIBRARYEXPORT_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// DYNAMICLIBRARYEXPORT_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
#ifdef DYNAMICLIBRARYEXPORT_EXPORTS
#define DYNAMICLIBRARYEXPORT_API __declspec(dllexport)	//导出项的(DLL)动态链接库模块使用,表导出,暴露给其他模块的接口函数,类,对象。
#else
#define DYNAMICLIBRARYEXPORT_API __declspec(dllimport)	//源文件中包含此文件的任何其他项目使用,表接口函数,类,对象来自其他模块导出。
#endif

// 此类是从 dll 导出的
class DYNAMICLIBRARYEXPORT_API CDynamicLibraryExport {
public:
	CDynamicLibraryExport(void);
	// TODO: 在此处添加方法。
};

extern DYNAMICLIBRARYEXPORT_API int nDynamicLibraryExport;

DYNAMICLIBRARYEXPORT_API int fnDynamicLibraryExport(void);

4、查看动态库生成的接口
VS工具(或dependency walker):
VS2013为单击Windows图标------>所有程序------>找到相应的Visual Studio2013文件夹------->选择Visual Studio tool(会打开文件夹)-------->寻找本机工具命令提示。
VS2013为单击Windows图标------>所有程序------>找到相应的Visual Studio2017文件夹------->VS 2017的 x64_x86 交叉工具命令提示符。
切换到dll文件目录下,运行命令:dumpbin /EXPORTS 库名(例:dumpbin /EXPORTS DYNAMICLIBRARYEXPORT.dll)
静态链接库和动态链接库_第2张图片

三、静态链接和动态链接

1、静态库的链接
把调要调用的函数或者过程直接链接到可执行文件(dll或exe)中,成为可执行文件的一部分。该文件中包含了运行所需的全部代码。

优点:
链接该静态库可执行文件(dll或exe等)的使用,无需再需要该静态库。
缺点:
a)当多个程序都要调用相同函数时,内存中就会存在这个函数的多个复制,存在资源浪费。
b)当静态库发生修改时,不仅该静态库要从新编译,引用该静态库的模块都需要从新编译。

2、动态库的链接
动态链接调用的函数代码并没有被复制到应用程序的可执行文件中去,而是仅仅在其中加入了所调用函数的描述信息(往往是一些重定位信息)。仅当应用程序被装入内存开始运行时,在操作系统的管理下,才在应用程序与相应的动态链接库(dynamic link library,dll)之间建立链接关系。当要执行调用.dll文件中的函数时,根据链接产生的重定位信息,操作系统才转去执行.dll文件中相应的函数代码。
优点:
当修改动态库的代码,但重定位信息没有变化,引用该动态库的模块无需从新编译。当然,重定位信息发生改变,两者都需要从新编译。

3、动态库链接的方式
1)LoadLibrary(根据路径加载动态库)、GetProcAddress(根据函数名获取函数指针,可能为空,但只能在运行时发现)、FreeLibrary(卸载动态库)
2)具有导出项的(DLL)动态链接库可根据导出的lib和头文件隐式链接,在编译阶段就可检查头文件和lib是否配套。运行时再保证动态库和lib配套即可。

四、3种函数调用协议

__stdcall、__cdcel和__fastcall三者的区别https://www.cnblogs.com/yejianyong/p/7506465.html

五、问题(欢迎讨论)

1、extern、extern “C”、extern “C++”的不同
2、怎么导出导出重载函数?

如有错误或不足欢迎评论指出!创作不易,转载请注明出处。如有帮助,记得点赞关注哦(⊙o⊙)
更多内容请关注个人博客:https://blog.csdn.net/qq_43148810

你可能感兴趣的:(C++高级编程,dll,lib,动态链接库,静态链接库,C++)