静态链接库和动态链接库

article/2025/8/30 6:41:54

一、前言

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

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

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

2、制作方法
大胡子的艾娃
定义静态库的函数

#include "pch.h"
#include "framework.h"// TODO: 这是一个库函数示例
void fnStaticLibrary()
{
}

定义动态链接库(DLL)

#include <windows.h>
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)
请添加图片描述

三、静态链接和动态链接

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


http://chatgpt.dhexx.cn/article/a9i7hdvr.shtml

相关文章

linux之静态库与动态库

我们在写c语言的时候&#xff0c;经常会去包含一个.h的头文件&#xff0c;这个头文件就是库文件&#xff0c;比如<stdio.h>,<stdlib.h>这些都是标准的头文件&#xff0c;一般放在/usr/include,也就是说&#xff0c;从这个目录中我们可以找到这个头文件&#xff0c;…

理解和创建Windows和Linux下的动态和静态库区别

一、引言 在计算机编程的世界中&#xff0c;库是一个非常重要的改变。它的出现提供了一种共享和重用代码的可能性&#xff0c;复杂的程序因为动态库的出现而变得简洁和方便。然而&#xff0c;库并不是单一的&#xff1a;它们可以是动态的&#xff0c;也可以是静态的&#xff0…

静态库与动态库的区别和使用

动静态库所用到的一些库文件&#xff1a; .o 是目标对象文件,相当于windows中的.obj文件。可由一个或多个.c /.cpp来生成 .a 为静态库&#xff0c;可以是一个或多个.o合在一起,用于静态连接&#xff1b;多个.o文件可以链接生成一个.exe的可执行文件。静态库在程序编译时会被连…

静态库和动态库的使用与区别

引文 库文件是计算机上的一类文件&#xff0c;可以理解为一种代码仓库&#xff0c;提供给使用者一些可以直接使用的变量、函数或类。 库文件分为两类&#xff1a; 静态库&#xff1a;在链接阶段&#xff0c;会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中…

【Linux静态库和动态库】

Linux静态库和动态库 1. 编译与ELF格式2. 库的基本概念3.静态库的制作&#xff1a;&#xff08;假设要将a.c、b.c制作成静态库&#xff09;4.静态库的常见操作5.静态库的使用6. 多个库的相互依赖举例1.(库文件制作、错误处理) 7.静态库和动态库的关系和区别8.动态库的制作软链接…

如何理解静态库与动态库

究竟什么是库&#xff1a; 日常生活中有很多所谓的库&#xff0c;比如车库啊&#xff0c;优衣库啊&#xff0c;甚至还有一库&#xff08;日语&#xff09;咳咳。然后对程序员来说&#xff0c;所谓的库&#xff0c;即是程序库&#xff0c;当一段代码十分耐用&#xff0c;又经过…

C++静态库与动态库的区别

文章目录 什么是库静态库Linux下创建与使用静态库Windows下创建与使用静态库 动态库Linux下创建与使用动态库Windows下创建与使用动态库 动态库的显式调用在Linux下显式调用动态库在Windows下显式调用动态库显式调用C动态库注意点 附件&#xff1a;Linux下库相关命令g(gcc)编译…

动态库静态库的区别

1、动态库以及静态库区别 静态库是函数和数据编译进一个二进制文件里面&#xff08;.lib文件&#xff09;&#xff0c;在使用静态库链接成可执行程序的时候&#xff0c;链接器会复制静态库内的函数和数据进可执行程序里面(.EXE文件)&#xff0c;所以在加载库的时候不需要加载相…

详谈静态库和动态库的区别

一、什么是库&#xff1a; 库是写好的&#xff0c;现有的&#xff0c;成熟的&#xff0c;可以复用的代码。现实中每个程序都要依赖很多基础的底层库&#xff0c;不可能每个人的代码都从零开始&#xff0c;因此库的存在意义非同寻常。 本质上来说&#xff0c;库是一种可执行代…

【C语言】详解#define,#ifdef,#ifndef,#elif,#undef,以及相关运算符

1.明示常量 #define 预处理指令结尾不带&#xff1b;&#xff08;分号&#xff09;&#xff0c;在预编译的过程中使用宏的地方会进行展开&#xff0c;是用多少次就展开多少次&#xff0c;但是只替换 不计算&#xff0c;预处理器在发现程序中的宏后&#xff0c;会用宏等价的替换…

Vue 项目报错:‘$‘ is not defined ( no-undef )

错误描述 报错如上图所示&#xff0c;错误原因是不认识 $ 符&#xff0c;他是 JQuery 中得符号&#xff0c;我也确实引入了 JQuery&#xff1a; 解决办法 在 vue 项目的根目录下创建一个 .eslinttrc.js 文件&#xff0c;文件内容如下&#xff1a; module.exports {root: true…

undefined和is not defined区别

undefined定义&#xff1a; undefined是javascript的一种基本数据类型&#xff0c;变量未赋值或者函数没有返回值时返回。 xxx is not defined是一种错误类型&#xff0c;其完整形式是&#xff1a;Uncaught ReferenceError: xxx is not defined&#xff08;未捕获的引用错误&a…

#define #undef等基本知识

1、预处理符号 例子&#xff1a; #include <stdio.h> #define DEBUG_PRINT printf("FILE %s line %d:" \"x%d, y%d, z%d," \__FILE__,__LINE__,x,y,z) //或者如下: //#define DEBUG_PRINT printf( "File %s line %d:…

undefined和is not defined一样吗?

https://blog.csdn.net/sheldon178/article/details/48298151/ undefined和is not defined&#xff0c;字面意思看来没什么两样&#xff0c;不都是未定义吗&#xff1f; 在JavaScript中&#xff0c;可并非如此。 undefined定义如下&#xff1a; undefined是javascript的一种…

C++中 #define 与 #undef

define 宏指令 #define 与 # include类似,它的好处呢就是速度快,使用define定义函数可以减少函数调用的额外开销 define 主要体现在2个地方 1 定义一个值 2 定义一个函数或者说功能 #include <iostream> using namespace std; // 定义一个值 #define HELLO_WORLD "…

#define #undef 使用

#define 是宏定义 #define 的用法是非常多功能的&#xff0c;它不止能实现常量宏定义&#xff0c;开关&#xff0c;还能实现函数 #undef 是取消宏定义 在undef后面要加上你要取消的宏定义 不想取消在后面可以瞎写但是不能为空 例子 #include "stdio.h"int main(…

C语言 #undef的用法

C语言中#undef的语法定义是&#xff1a;#undef 标识符&#xff0c;用来将前面定义的宏标识符取消定义。 然而&#xff0c;在实际应用中&#xff0c;#undef到底可以用来做什么&#xff1f; 整理了如下几种#undef的常见用法。 1. 防止宏定义冲突 在一个程序块中用完宏定义后&…

Perl学习-undef值和defined函数

undef值 undef是未定义的意思&#xff0c;在Perl中&#xff0c;会假设undef的变量时0或者空字符串 如果当成数字&#xff0c;就是0如果当成字符串&#xff0c;就是空字符串 当成数字 1 $n 1;2 3 while($n < 10){4 $sum $n;5 $n 2;6 }7 8 print "The tota…

吊打迅雷,最好用的BT种子下载器,下载不限速

今天小七要给大家带来的是一款安卓端BT下载器&#xff0c;用它来找片&#xff0c;下片&#xff0c;简直爽到极点&#xff0c;目前完全免费&#xff0c;无广告、无会员限制、极速下载、运行稳定支持多种格子解析、支持边下边播等等&#xff0c;拥有迅雷的所有功能&#xff0c;同…

比迅雷好用,下载速度快5倍的下载软件IDM(Internet Download Manager)

家好&#xff0c;很高兴大家阅读本文章&#xff0c;我一直在做自媒体&#xff0c;而且自媒体现在也当自己的一份工作来做了&#xff0c;那么在做自媒体的过程&#xff0c;肯定也会需要找素材&#xff0c;而在找素材的过程中需要用到下载工具&#xff0c;大家说说看现在国内&…