linux下静态库与动态库的区别
linux动态库静态库函数覆盖

linux动态库静态库函数覆盖本⽂讨论了linux动态库静态库中函数的覆盖问题。
测试⽬的:同名函数,分别打成动态库libdync_lib.so与静态库libstatic_lib.a,并把libstatic_lib.a打到另⼀个动态库libapi.so中,在可执⾏程序中分别连接libdync_lib.so与libapi.so,此时到底调⽤的是哪个库中的函数?测试结论:不同库中的同名函数会被覆盖,后链接的库中的同名函数会被先前库覆盖。
测试⽅法:static_lib.h1void print();static_lib.cpp1 #include <cstdio.h>2 #include "static_lib.h"34void print()5 {6 printf("i am static print\n");7 }dync_lib.h1void print();dync_lib.cpp#include <cstdio.h>#include "dync_lib.h"void print(){printf("i am dync print\n");}api.hvoid func();api.cpp1 #include "static_lib.h"23void func()4 {5 print();6 }main.cpp#include <api.h>int main(){func();print();return0;}制作libdync_lib.so动态库g++ dync_lib.cpp -shared -fPIC -o libdync_lib.so制作libstatic_lib.a静态库g++ -c static_lib.cpp -share -fPIC -o static_lib.oar crv libstatic_lib.a static_lib.o制作libapi.so动态库,其依赖静态库libstatic_lib.ag++ api.cpp -shared -fPIC -o libapi.so -lstatic_lib有三种⽅式⽣成可执⾏程序1、g++ main.cpp -lapi -o main2、g++ main.cpp -lapi -ldync_lib -o main3、g++ main.cpp -ldync_lib -lapi -o main每种⽅式都能执⾏成功,但输出不⼀样,1、2执⾏时,输出⼀致:i am static print3执⾏时,输出;i am dync print下⾯分析原因:1、第⼀种⽅式中,main.cpp中只包含了 api.h,⽽api.h中并没有定义print函数,那么main中怎么找到了该函数并且调⽤成功了呢?因为,⽣成libapi.so时连接了libstatic_lib.a,⽽其中包含print,也就是说,静态库中的函数符号都会被打到动态库中,所以main能找到print 函数的实现,来⾃libstatic_lib.a。
静态链接库和动态链接库的区别及优缺点

静态链接库和动态链接库的区别及优缺点动态链接库和静态链接库的区别本⽂参考了以下博客:1. /gamecreating/article/details/55041522. /left_la/article/details/120985453. /augusdi/article/details/6460415静态连接库就是把(lib)⽂件中⽤到的函数代码直接链接进⽬标程序,程序运⾏的时候不再需要其它的库⽂件;动态链接就是把调⽤的函数所在⽂件模块(DLL)和调⽤函数在⽂件中的位置等信息链接进⽬标程序,程序运⾏的时候再从DLL中寻找相应函数代码,因此需要相应DLL⽂件的⽀持。
静态链接库与动态链接库都是共享代码的⽅式,如果采⽤静态链接库,则⽆论你愿不愿意,lib 中的指令都全部被直接包含在最终⽣成的 EXE ⽂件中了。
但是若使⽤ DLL,该 DLL 不必被包含在最终 EXE ⽂件中,EXE ⽂件执⾏时可以“动态”地引⽤和卸载这个与 EXE 独⽴的 DLL ⽂件。
静态链接库和动态链接库的另外⼀个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,⽽在动态链接库中还可以再包含其他的动态或静态链接库。
动态库就是在需要调⽤其中的函数时,根据函数映射表找到该函数然后调⼊堆栈执⾏。
如果在当前⼯程中有多处对dll⽂件中同⼀个函数的调⽤,那么执⾏时,这个函数只会留下⼀份拷贝。
但是如果有多处对lib⽂件中同⼀个函数的调⽤,那么执⾏时,该函数将在当前程序的执⾏空间⾥留下多份拷贝,⽽且是⼀处调⽤就产⽣⼀份拷贝。
静态链接库与静态链接库调⽤规则总体⽐较如下:1、静态链接库(⽐较简单):⾸先,静态链接库的使⽤需要库的开发者提供⽣成库的.h头⽂件和.lib⽂件。
⽣成库的.h头⽂件中的声明格式如下:extern "C" 函数返回类型函数名(参数表);在调⽤程序的.cpp源代码⽂件中如下:#include "../lib.h"#pragma comment(lib,"..//debug//libTest.lib") //指定与静态库⼀起链接其次因为静态链接库是将全部指令都包含⼊调⽤程序⽣成的EXE⽂件中。
linux动态库和静态库调用方法

linux动态库和静态库调用方法
在Linux操作系统中,动态库和静态库的调用方法如下:
1. 动态库(Shared Library):动态库在程序运行时被载入内存,可以被多个程序同时使用,节省内存空间。
在Linux中,动态库一般存放在/usr/lib或/lib目录下。
调用方法:在程序中使用extern "C"来声明函数接口,然后通过dlopen(), dlsym()等函数来动态调用动态库中的函数。
2. 静态库(Static Library):静态库在程序编译时被包含进可执行程序中,每个程序都有一份自己的库副本。
静态库一般存放在/usr/lib或/lib目录下。
调用方法:在程序中直接使用静态库中的函数,不需要额外的调用方法。
只需要在编译时使用"-l"选项指定要链接的库名,例如"gcc -o test test.c -lmylib"。
需要注意的是,对于动态库和静态库的使用,一般建议优先使用动态库,因为这样可以节省内存空间,并且可以在不停止程序运行的情况下更新库文件。
第1页/ 共1页。
库文件的应用原理是啥啊

库文件的应用原理是啥啊什么是库文件在计算机编程中,库文件指的是一组已经编译好的代码和相关数据,供开发人员在编程过程中重用。
库文件可以包含函数、类、变量和常量等代码元素,以及相关的文档和示例等。
使用库文件可以大大提高开发效率,避免重复编写相同的代码,同时也可以提供可靠和经过测试的功能。
库文件的种类库文件有多种类型,常见的包括:1.静态库:静态库在编译时会被完整地链接到最终的可执行程序中。
使用静态库意味着库的代码和数据会被复制到最终的程序中,因此程序在运行时不需要额外的依赖。
但缺点是静态库的更新需要重新编译整个程序。
2.动态库:动态库在程序运行时被加载到内存中,并在需要时进行链接。
多个程序可以共享同一个动态库,从而减少了内存的占用。
动态库的更新只需要替换库文件即可,无需重新编译程序。
3.共享库:共享库是一种特殊的动态库,可以在运行时被多个程序共享。
共享库的好处是减少了磁盘空间的占用,并提供了一种独立于应用程序的模块化设计思想。
4.框架:框架是一种高度集成的库文件,通常包括多个相关的静态库、动态库和资源文件等。
框架通常用于开发特定类型的应用程序或功能模块,提供了一套完整的开发工具和规范。
库文件的应用原理库文件的应用原理主要包括以下几个方面:1. 封装和抽象库文件的设计基于软件工程的封装和抽象原则,将一组相关的代码封装成函数、类或模块等开发单位,隐藏了内部的实现细节,只暴露必要的接口给外部使用。
通过封装和抽象,库文件提供了一种方便、可复用和可拓展的编程方式,使开发人员能够更加高效地完成开发任务。
2. 模块化和组件化库文件的设计应当遵循模块化和组件化的原则,将不同功能的代码分割成独立的模块或组件,通过接口和依赖关系进行连接。
这样可以使代码更加可读、可维护和可测试,同时也方便了团队协作和代码复用。
3. 提供标准接口库文件通常会提供一组标准接口,供开发人员进行调用。
这些接口定义了库文件的功能和使用方法,使得开发人员能够很方便地使用库文件提供的功能。
动态库底层运行原理

动态库底层运行原理1.引言1.1 概述概述部分内容:引言部分将对动态库底层运行原理的概述进行介绍。
动态库作为一种重要的软件开发工具,在各种编程语言中都有广泛的应用。
它与静态库相对应,是一种在程序运行时动态加载的库文件。
相比静态库,动态库具有更好的灵活性和扩展性。
文章将从动态库的定义开始介绍,然后深入探讨动态库的加载和链接过程。
动态库的定义是指对动态库的基本概念和特点进行解释,包括其存储结构、运行机制等方面的内容。
动态库具有独立的文件形式,其中包含了可执行代码、数据以及其他资源。
它可以被多个程序共享,并且可以在运行时动态加载到内存中,以提供额外的功能和服务。
接下来,文章将详细介绍动态库的加载和链接机制。
动态库的加载和链接过程是指将动态库中的代码和数据与主程序进行关联,使得程序能够正确地调用并执行其中定义的函数和方法。
加载指的是将动态库的文件映射到内存中,并为其分配合适的内存空间。
链接则是处理动态库与主程序之间的符号引用和重定位等问题,确保动态库能够正确地被主程序所调用和使用。
本文的目的是为读者提供一个全面的理解动态库底层运行原理的基础知识,帮助读者更好地理解和应用动态库。
在接下来的正文部分,将逐步展开对动态库的定义、加载和链接过程的详细解析。
最后的结论部分将总结动态库底层运行原理的重要性和应用,并对未来动态库的发展趋势进行展望。
1.2 文章结构本篇文章主要分为引言、正文和结论三个部分。
1. 引言部分概述了本文的主题和目的。
首先,我们对动态库底层运行原理进行了简要的概述,介绍了它在软件开发中的重要性和应用范围。
其次,我们介绍了本文的结构和内容安排,为读者提供了一个整体的框架。
2. 正文部分是本文的核心部分,详细介绍了动态库的定义、加载和链接过程。
在2.1节中,我们将对动态库的定义进行详细说明,包括它与静态库的区别和优势。
在2.2节中,我们将详细探讨动态库的加载和链接过程,包括动态库的加载方式、符号解析和重定位等。
Linux_3_编译工具链

编译工具链前面我们写程序的时候用的都是集成开发环境(IDE: Integrated Development Environment),集成开发环境可以极大地方便我们程序员编写程序,但是配置起来也相对麻烦。
在 Linux 环境下,我们用的是编译工具链,又叫软件开发工具包(SDK: Software Development Kit)。
Linux 环境下常见的编译工具链有:GCC 和 Clang,我们使用的是 GCC。
1编译gcc、g++分别是 gnu 下的 c 和 c++编译器。
$ sudo a pt inst a ll g cc gd b# 安装g cc和gd b$ g cc-v# 查看g cc的版本在讲如何编译之前,有必要给大家回顾一下生成可执行程序的整个过程:对应的 gcc 命令如下:g cc-E hello.c-o hello.i# -E激活预处理,生成预处理后的文件g cc-S hello.i-o hello.s# —S激活预处理和编译,生成汇编代码g cc-c hello.s-o hello.o# -c激活预处理、编译和汇编,生成目标文件g cc hello.o-o hello# 执行所有阶段,生成可执行程序其实没必要指定每一个步骤,我们常常会这样用:g cc-c hello.c# 生成目标文件,g cc会根据文件名hello.c生成hello.og cc hello.o-o hello# 生成可执行程序hello,这里我们需要指定可执行程序的名称,否则会默认生成a.out甚至有时候,我们会一步到位:g cc hello.c-o hello# 编译链接,生成可执行程序hello1.1G C C其它选项选项含义-Wall生成所有警告信息-O0,-O1,-O2,-O3编译器的4个优化级别,-O0表示不优化,-O1为缺省值,-O3的优化级别最高-g指示编译器在编译的时候产生调试相关的信息。
(调试程序必须加上这个选项)-Dmacro相当于在文件的开头加了#define macro-Dmacro=value相当于在文件的开头加了#define macro value-Idir对于#include "file",gcc/g++会先在当前目录查找你所指定的头文件,如果没有找到,他会到系统的 include 目录找.如果使用-I 指定了目录,他会先在你所指定的目录查找,然后再按常规的顺序去找。
静态链接库与动态链接库的异同点

先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量、函数或类。
在仓库的发展史上经历了“无库-静态链接库-动态链接库”的时代。
静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib 中的指令都被直接包含在最终生成的EXE文件中了。
但是若使用DLL,该DLL不必被包含在最终EXE文件中,EXE文件执行时可以“动态”地引用和卸载这个与EXE独立的DLL文件。
静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。
目标库(Object Libraries)目标库又叫静态链接库,是扩展名为.LIB的文件,包括了用户程序要用到的各种函数。
它在用户程序进行链接时,“静态链接”到可执行程序文件当中。
例如,在VC++中最常使用到的C运行时目标库文件就是LIBC.LIB。
在链接应用程序时常使用所谓“静态链接”的方法,即将各个目标文件(.obj)、运行时函数库(.lib)以及已编译的资源文件(.res)链接到一起,形成一个可执行文件(.exe)。
使用静态链接时,可执行文件需要使用的各种函数和资源都已包含到文件中。
这样做的缺点是对于多个程序都使用的相同函数和资源要重复链接到exe 文件中,使程序变大、占用内存增加。
动态链接库(Dynamic-Link Libraries)“动态链接”是将一些公用的函数或资源组织成动态链接库文件(.dll),当某个需要使用dll中的函数或资源的程序启动时(准确的说是初始化时),系统将该dll映射到调用进程的虚拟地址空间、增加该dll的引用计数值,然后当实际使用到该dll时操作系统就将该dll载入内存;如果使用该dll的所有程序都已结束,则系统将该库从内存中移除。
使用同一dll的各个进程在运行时共享dll 的代码,但是对于dll中的数据则各有一份拷贝(当然也有在dll中共享数据的方法)。
linux.o,.a,.so文件解析

linux.o,.a,.so⽂件解析linux下⽂件的类型是不依赖于其后缀名的,但⼀般来讲:.o,是⽬标⽂件,相当于windows中的.obj⽂件.so 为共享库,是shared object,⽤于动态连接的,和dll差不多.a为静态库,是好多个.o合在⼀起,⽤于静态连接.la为libtool⾃动⽣成的⼀些共享库,vi编辑查看,主要记录了⼀些配置信息。
可以⽤如下命令查看*.la⽂件的格式 $file *.la*.la: ASCII English text所以可以⽤vi来查看其内容。
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@创建.a库⽂件和.o库⽂件:[yufei@localhost perl_c2]$ pwd/home/yufei/perl_c2[yufei@localhost perl_c2]$ cat mylib.c#include#includevoid hello(){printf("success call from perl to c library\n");}[yufei@localhost perl_c2]$ cat mylib.hextern void hello();[yufei@localhost perl_c2]$ gcc -c mylib.c[yufei@localhost perl_c2]$ dirmylib.c mylib.h mylib.o[yufei@localhost perl_c2]$ ar -r mylib.a mylib.oar: 正在创建 mylib.a[yufei@localhost perl_c2]$ dirmylib.a mylib.c mylib.h mylib.o@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111动态链接库*.so的编译与使⽤- -动态库*.so在linux下⽤c和c++编程时经常会碰到,最近在⽹站找了⼏篇⽂章介绍动态库的编译和链接,总算搞懂了这个之前⼀直不太了解得东东,这⾥做个笔记,也为其它正为动态库链接库⽽苦恼的兄弟们提供⼀点帮助。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
静态库与动态库什么是库库是写好的,现有的,成熟的,可以复用的代码。
现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。
本质上来说,库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。
库有两种:静态库(.a、.lib)和动态库(.so、.dll)。
所谓静态、动态是指链接。
回顾一下,将一个程序编译成可执行程序的步骤:静态库之所以称为【静态库】,是因为在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。
因此对应的链接方式称为静态链接。
试想一下,静态库与汇编生成的目标文件一起链接为可执行文件,那么静态库必定跟.o文件格式相似。
其实一个静态库可以简单看成是一组目标文件(.o/.obj 文件)的集合,即很多目标文件经过压缩打包后形成的一个文件。
静态库特点总结如下:➢静态库对函数库的链接是放在编译时期完成的。
➢程序在运行时与函数库再无瓜葛,移植方便。
➢浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。
Linux下创建与使用静态库Linux静态库命名规则Linux静态库命名规范,必须是"lib[your_library_name].a":lib为前缀,中间是静态库名,扩展名为.a。
创建静态库(.a)通过上面的流程可以知道,Linux创建静态库过程如下:•首先,将代码文件编译成目标文件.o(StaticMath.o)g++ -c StaticMath.cpp注意带参数-c,否则直接编译为可执行文件•然后,通过ar工具将目标文件打包成.a静态库文件ar -crv libstaticmath.a StaticMath.o生成静态库libstaticmath.a图3.Linux下使用静态库大一点的项目会编写makefile文件(CMake等等工程管理工具)来生成静态库,输入多个命令太麻烦了。
使用静态库Linux下使用静态库,只需要在编译的时候,指定静态库的搜索路径(-L选项)、指定静态库名(不需要lib前缀和.a后缀,-l选项)。
g++ TestStaticLibrary.cpp -L../StaticLibrary -lstaticmath•-L:表示要连接的库所在目录•-l:指定链接时需要的库,编译器查找连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.a或.so来确定库的名称。
动态库通过上面的介绍,发现静态库容易使用和理解,也达到了代码复用的目的,那为什么还需要动态库呢?为什么还需要动态库?为什么还需要动态库,其实也就是静态库的特点导致。
•空间浪费是静态库的一个问题。
•另一个问题是静态库对程序的更新、部署和发布页会带来麻烦。
如果静态库libxx.lib更新了,所有使用它的应用程序都需要重新编译、发布给用户(对于玩家来说,只是一个很小的改动,却导致整个程序重新下载,全量更新)。
动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。
不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。
动态库在程序运行时才被载入,也解决了静态库对程序的更新、部署和发布页会带来麻烦。
用户只需要更新动态库即可,增量更新。
动态库特点总结:•动态库把对一些库函数的链接载入推迟到程序运行的时期。
•可以实现进程之间的资源共享。
(因此动态库也称为共享库)•将一些程序升级变得简单。
•甚至可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)。
Windows与Linux执行文件格式不同,在创建动态库的时候有一些差异。
•在Windows系统下的执行文件格式是PE格式,动态库需要一个DllMain函数做初始化的入口,通常在导出函数的声明时需要有_declspec(dllexport)关键字。
•Linux下gcc编译的执行文件默认是ELF格式,不需要初始化入口,亦不需要函数做特别的声明,编写比较方便。
与创建静态库不同的是,不需要打包工具(ar、lib.exe),直接使用编译器即可创建动态库。
Linux下创建与使用动态库linux动态库的命名规则动态链接库的名字形式为libxxx.so,前缀是lib,后缀名为“.so”。
•针对于实际库文件,每个共享库都有个特殊的名字“so name”。
在程序启动后,程序通过这个名字来告诉动态加载器,该载入哪个共享库。
•在文件系统中,soname仅是一个链接到实际动态库的链接。
对于动态库而言,每个库实际上都有另一个名字给编译器来用。
它是一个指向实际库镜像文件的链接文件(lib+soname+.so)。
创建动态库(.so)g++ -fPIC -shared -o libdynmath.so DynamicMath.cpp总结二者的不同点在于代码被载入的时刻不同。
•静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库,因此体积较大。
•动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在,因此代码体积较小。
动态库的好处是,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。
带来好处的同时,也会有问题!如经典的DLL Hell问题,关于如何规避动态库管理问题,可以自行查找相关资料。
附录动态库测试代码:什么是库库是写好的,现有的,成熟的,可以复用的代码。
现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。
本质上来说,库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。
库有两种:静态库(.a、.lib)和动态库(.so、.dll)。
所谓静态、动态是指链接。
回顾一下,将一个程序编译成可执行程序的步骤:图1.编译过程静态库之所以称为【静态库】,是因为在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。
因此对应的链接方式称为静态链接。
试想一下,静态库与汇编生成的目标文件一起链接为可执行文件,那么静态库必定跟.o文件格式相似。
其实一个静态库可以简单看成是一组目标文件(.o/.obj 文件)的集合,即很多目标文件经过压缩打包后形成的一个文件。
静态库特点总结如下:•静态库对函数库的链接是放在编译时期完成的。
•程序在运行时与函数库再无瓜葛,移植方便。
•浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。
下面编写一些简单的四则运算C++类,将其编译成静态库给他人用,头文件如下所示:1 #pragma once2 class StaticMath3 {4 public:5 StaticMath(void);6 ~StaticMath(void);78 static double add(double a, double b);//加法9 static double sub(double a, double b);//减法10 static double mul(double a, double b);//乘法11 static double div(double a, double b);//除法1213 void print();14 };Linux下使用ar工具、Windows下vs使用lib.exe,将目标文件压缩到一起,并且对其进行编号和索引,以便于查找和检索。
一般创建静态库的步骤如图所示:图2.创建静态库过程Linux下创建与使用静态库Linux静态库命名规则Linux静态库命名规范,必须是"lib[your_library_name].a":lib为前缀,中间是静态库名,扩展名为.a。
创建静态库(.a)通过上面的流程可以知道,Linux创建静态库过程如下:•首先,将代码文件编译成目标文件.o(StaticMath.o)g++ -c StaticMath.cpp注意带参数-c,否则直接编译为可执行文件•然后,通过ar工具将目标文件打包成.a静态库文件ar -crv libstaticmath.a StaticMath.o生成静态库libstaticmath.a图3.Linux下使用静态库大一点的项目会编写makefile文件(CMake等等工程管理工具)来生成静态库,输入多个命令太麻烦了。
使用静态库编写使用上面创建的静态库的测试代码:1 #include "StaticMath.h"2 #include <iostream>3 using namespace std;45 int main(int argc, char* argv[])6 {7 double a = 10;8 double b = 2;910 cout << "a + b = " << StaticMath::add(a, b) << endl;11 cout << "a - b = " << StaticMath::sub(a, b) << endl;12 cout << "a * b = " << StaticMath::mul(a, b) << endl;13 cout << "a / b = " << StaticMath::div(a, b) << endl;1415 StaticMath sm;16 sm.print();1718 system("pause");19 return 0;20 }Linux下使用静态库,只需要在编译的时候,指定静态库的搜索路径(-L选项)、指定静态库名(不需要lib前缀和.a后缀,-l选项)。
g++ TestStaticLibrary.cpp -L../StaticLibrary -lstaticmath•-L:表示要连接的库所在目录•-l:指定链接时需要的库,编译器查找连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.a或.so来确定库的名称。
Windows下创建与使用静态库创建静态库(.lib)如果是使用VS命令行生成静态库,也是分两个步骤来生成程序:•首先,通过使用带编译器选项/c的Cl.exe编译代码(cl /c StaticMath.cpp),创建名为“StaticMath.obj”的目标文件。
•然后,使用库管理器Lib.exe链接代码 (lib StaticMath.obj),创建静态库StaticMath.lib。