陕西门户网站建设,嘉定郑州阳网站建设,广州网站建设与网页设计,网站的seo优化报告文章目录 动态链接库和静态链接库什么是链接库#xff1f;静态链接库动态链接库动态链接库的俩种链接方式加载时动态链接运行时动态链接 动态链接库和静态链接库
动态链接库和静态链接库都是共享代码的方法#xff0c;只是二者略有区别。
以C/C为例#xff0c;一个可执行文… 文章目录 动态链接库和静态链接库什么是链接库静态链接库动态链接库动态链接库的俩种链接方式加载时动态链接运行时动态链接 动态链接库和静态链接库
动态链接库和静态链接库都是共享代码的方法只是二者略有区别。
以C/C为例一个可执行文件的生成主要包括预编译、编译、汇编和链接。而静态链接和动态链接就是 在链接阶段的俩种处理。
什么是链接库
关于代码复用有些文件专门用于存储可以重复使用的代码块例如功能实用的函数或者类我们通常将它们称为库文件简称“库”Library。将这种库文件进行打包编译后得到二进制文件就是链接库。
链接库是一个不能独立运行的二进制文件它必须经过其他程序调用才可以载入内存中。
根据链接方式的不同可以分为静态链接库和动态链接库
静态链接库
所谓静态链接就是在程序执行前将所有目标文件同静态链接库一起组织成可执行文件这样生成的可执行文件可以独立运行。
采用静态链接库的方式共享代码有一个明显的缺点那就是文件的体积会很大因为可执行文件包含了所有目标文件和静态链接库的数据。这样容易造成内存空间的浪费。同时不利用代码的模块化如果有某个模块需要更新整个程序都需要重新连接才能运行。
若是有多个程序调用相同函数内存中就会存在这个函数的多个拷贝。
动态链接库
动态链接是相对静态链接而言的动态链接所调用的代码并没有被打包到可执行文件中被拷贝的往往只是某些函数的描述信息如重定位信息只有当程序执行的过程中需要调用到动态库中的函数式动态链接库中的函数才会被载入内存中。
一般情况下一个程序如果使用了动态链接库系统会保证内存中只有一份DLL的复制品。
动态链接库可以随可执行文件一同载入内存也可以在可执行文件运行过程中载入即可执行文件什么时候需要动态链接库才会载入内存。
采用动态链接库方便程序的更新当程序的某个模块更新后只需要将旧的模块替换掉程序运行时会自动将所有模板载入内存并动态地链接在一起。
但是动态链接库也有一定的缺点静态链接生成的可执行文件能够在其他同类操作系统上直接运行。但是如果是动态链接生成的文件在移植到其他操作系统上后需要连同该可执行文件所调用到的DLL文件一并拷贝过去不然不能保证程序的正常运行。
动态链接库的俩种链接方式
动态链接实际上还有俩种不同的连接方式加载时动态链接和运行时动态链接隐式加载和显式加载
加载时动态链接
在加载时动态链接中应用程序像本地函数一样显式调用导出的 DLL 函数。要使用加载时动态链接请在编译和链接应用程序时提供头文件 (.h) 和导入库 (.lib) 文件。执行此操作时链接器将为系统提供加载 DLL 所需的信息并在加载时解析导出的 DLL 函数位置。
使用加载时动态链接同静态链接有一个相同的缺点那就是如果程序的体积稍大程序开始时加载的时间就会过长。
加载时动态链接和静态链接的区别
链接的时机加载时动态链接是在程序加载时程序才会将动态库载入到内存中而静态链接则是在编译的时候就已经将静态库的代码和数据嵌入到可执行文件中了。
正如上面所说的使用加载时动态链接需要提供头文件 (.h) 和导入库 (.lib) 文件。可以直接在源码中引入.lib文件。
例如
#pragma comment(lib, dllDemo.lib)为了更好的模块化设计也可以将lib中所要用到函数声明放在头文件中。
例如
//dllDemo.h
#ifndef _DLLDEMO_H
#DEFINE _DLLDEMO_H#pragma comment(lib,dllDemo.lib)
_declspec(dllexport) int add(int, int);
_declspec(dllexport) int sub(int, int);#endif
之后的主程序中记得
#include dllDemo.h上述代码还用了_declspec(dllimport) 标识符声明函数来自动态链接库。
运行时动态链接
在运行时动态链接中应用程序调用LoadLibrary 函数或LoadLibraryEx 函数在运行时加载DLL。 DLL成功加载后可以使用GetProcAddress函数获取要调用的导出DLL函数的地址。当您使用运行时动态链接时不需要导入库文件。
LoadLibrary 函数的作用是将指定的模块加载到调用进程的地址空间中。
函数定义
HMODULE LoadLibraryA([in] LPCSTR lpLibFileName //模块的名称。这可以是库模块.dll 文件也可以是可执行模块(.exe文件)
);如果调用成功将会返回该模块的句柄。
当得到该模块的句柄后可以使用GetProcAddress函数它从指定的动态链接库 (DLL) 检索导出函数也称为过程或变量的地址。
函数原型
FARPROC GetProcAddress([in] HMODULE hModule, //该模块的句柄[in] LPCSTR lpProcName //函数或变量的名称
);如果调用成功则返回导出函数或变量的地址。
示例
#include windows.hint main() {// 加载动态链接库HMODULE hLibrary LoadLibrary(example.dll);if (hLibrary ! NULL) {// 获取函数地址FARPROC functionAddress GetProcAddress(hLibrary, exampleFunction);if (functionAddress ! NULL) {// 调用动态链接库中的函数typedef void (*FunctionType)();FunctionType myFunction (FunctionType)functionAddress;myFunction();}// 卸载动态链接库FreeLibrary(hLibrary);}return 0;
}
以上关于运行时动态链接的实例是基于Windows的如果是在linux上使用运行时动态链接则需要通过使用 dlopen 和 dlsym以及 dlclose函数。
实例
#include dlfcn.hint main() {// 加载动态链接库void* libraryHandle dlopen(libexample.so, RTLD_LAZY);if (libraryHandle ! NULL) {// 获取函数地址void (*myFunction)() (void (*)())dlsym(libraryHandle, exampleFunction);if (myFunction ! NULL) {// 调用动态链接库中的函数myFunction();}// 卸载动态链接库dlclose(libraryHandle);}return 0;
}参考
https://learn.microsoft.com/en-us/troubleshoot/windows-client/deployment/dynamic-link-library
https://c.biancheng.net/dll/what_is_library.html
https://blog.csdn.net/fuzhongmin05/article/details/54616520
https://blog.csdn.net/u010154760/article/details/45689899?spm1001.2014.3001.5502