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++编程时经常会碰到,最近在⽹站找了⼏篇⽂章介绍动态库的编译和链接,总算搞懂了这个之前⼀直不太了解得东东,这⾥做个笔记,也为其它正为动态库链接库⽽苦恼的兄弟们提供⼀点帮助。
linux给运行程序指定动态库路径

linux给运⾏程序指定动态库路径1. 连接和运⾏时库⽂件搜索路径到设置库⽂件在连接(静态库和共享库)和运⾏(仅限于使⽤共享库的程序)时被使⽤,其搜索路径是在系统中进⾏设置的。
⼀般 Linux 系统把 /lib 和 /usr/lib 两个⽬录作为默认的库搜索路径【deepin可以在⾥⾯搜索出qt,因为deepin默认安装了qt程序运⾏依赖库】,所以使⽤这两个⽬录中的库时不需要进⾏设置搜索路径即可直接使⽤。
对于处于默认库搜索路径之外的库,需要将库的位置添加到库的搜索路径之中。
设置库⽂件的搜索路径有下列两种⽅式,可任选其⼀使⽤:(1). 在 /etc/ld.so.conf ⽂件中添加库的搜索路径。
(或者在/etc/ld.so.conf.d 下新建⼀个.conf⽂件,将搜索路径⼀⾏⼀个加⼊-junziyang)将⾃⼰可能存放库⽂件的路径都加⼊到/etc /ld.so.conf中是明智的选择添加⽅法也极其简单,将库⽂件的绝对路径直接写进去就OK了,⼀⾏⼀个。
例如:/usr/X11R6/lib/usr/local/lib/opt/lib需要注意的是:这种搜索路径的设置⽅式对于程序连接时的库(包括共享库和静态库)的定位已经⾜够了,但是对于使⽤了共享库的程序的执⾏还是不够的。
这是因为为了加快程序执⾏时对共享库的定位速度,避免使⽤搜索路径查找共享库的低效率,所以是直接读取库列表⽂件 /etc/ld.so.cache 从中进⾏搜索的。
/etc/ld.so.cache 是⼀个⾮⽂本的数据⽂件,不能直接编辑,它是根据 /etc/ld.so.conf 中设置的搜索路径由 /sbin/ldconfig 命令将这些搜索路径下的共享库⽂件集中在⼀起⽽⽣成的(ldconfig 命令要以 root 权限执⾏)。
因此,为了保证程序执⾏时对库的定位,在 /etc/ld.so.conf 中进⾏了库搜索路径的设置之后,还必须要运⾏/sbin/ldconfig 命令更新 /etc/ld.so.cache ⽂件之后才可以。
动态库依赖动态库,静态库依赖静态库,顺序

动态库依赖动态库,静态库依赖静态库,顺序静态库依赖静态库,有顺序的问题,否则undefined reference⾄于动态链接,链接器会对依赖进⾏整理,避免这个问题。
动态库就不存在依赖顺序的问题。
如果库是相互独⽴的,则顺序不重要。
如果不是相互独⽴,那么必须对它们进⾏排序对于⽇常命令⾏编译命令,⼀般从左到右分别是可执⾏⽂件 ——> ⾼级库 ——> 底层库,避免循环依赖;越是底层的库,越是往后⾯写,可以参考下述命令通式:g++ ... obj($?) -l(上层逻辑lib) -l(中间封装lib) -l(基础lib) -l(系统lib) -o $@静态库有顺序问题,并且要把⾃⼰的库所依赖的所有的第三⽅库都要显⽰的指定出来。
动态库⽆顺序问题,并且只需要显⽰的连接⾃⼰的动态库,⾃⼰的动态库依赖的第三⽅的动态库⽆需显⽰指定,⾃⼰会从rpath中⾃动连接第三⽅的动态库。
但必须把第三⽅库依赖的所有的库,包括路径都拷贝出来。
例如使⽤libevent.so, 此时需要把下⾯这⼀堆⽂件都拷贝出来:lrwxrwxrwx. 1 root root 21 Mar 25 15:18 deps/so/libevent-2.1.so.7 -> libevent-2.1.so.7.0.1-rwxr-xr-x. 1 root root 386024 Mar 25 15:18 deps/so/libevent-2.1.so.7.0.1lrwxrwxrwx. 1 root root 26 Mar 25 15:17 deps/so/libevent_core-2.1.so.7 -> libevent_core-2.1.so.7.0.1-rwxr-xr-x. 1 root root 241936 Mar 25 15:17 deps/so/libevent_core-2.1.so.7.0.1lrwxrwxrwx. 1 root root 26 Mar 25 15:17 deps/so/libevent_core.so -> libevent_core-2.1.so.7.0.1lrwxrwxrwx. 1 root root 21 Mar 25 15:18 deps/so/libevent.so -> libevent-2.1.so.7.0.1把第三⽅静态库链接到⾃⼰的.so动态库,编译第三⽅静态库的时候需要加 -fPIC这个参数。
linux动态库调用方法

linux动态库调用方法Linux动态库调用方法动态库是一种程序库,它在程序运行时才会被加载和链接,相对于静态库来说,动态库更加灵活和高效。
在Linux系统中,动态库的调用方法有多种,本文将介绍其中的一些常用方法。
1. 静态调用静态调用是指在编译链接阶段将动态库的代码完全复制到可执行文件中,使得可执行文件不再依赖于动态库。
在Linux系统中,静态调用需要使用静态库文件(以.a为后缀),可以通过在编译命令中添加-l参数来指定静态库文件的路径。
例如:```gcc main.c -L/path/to/lib -lmylib -o main```其中,/path/to/lib是动态库所在的路径,mylib是动态库的名称,main是生成的可执行文件名。
2. 动态调用动态调用是指在程序运行时动态加载和链接动态库。
在Linux系统中,动态调用需要使用动态库文件(以.so为后缀),可以通过以下几种方法进行动态调用。
(1)dlopen/dlsymdlopen和dlsym是Linux系统提供的动态库加载和符号查找函数。
dlopen函数用于加载动态库,dlsym函数用于查找动态库中的符号。
可以通过以下代码进行调用:```c#include <dlfcn.h>void* handle = dlopen("/path/to/libmylib.so", RTLD_LAZY);if (handle == NULL) {printf("Failed to load library: %s\n", dlerror());return -1;}void (*function)() = dlsym(handle, "my_function");if (function == NULL) {printf("Failed to find symbol: %s\n", dlerror());dlclose(handle);return -1;}function();dlclose(handle);```其中,/path/to/libmylib.so是动态库所在的路径,my_function 是动态库中的函数名。
配置管理作业指导书

配置管理作业指导书1. 目的为软件工程的配置管理过程中的一些过程执行提供指导性说明,以提高工作效率及统一工作思路;2. 配置管理库说明♦类型分:动态库、基线库、静态库⏹动态库:主要用于开发小组的日常开发;开发人员可以根据权限自由的进展Update/Commit;⏹基线库:主要用于保存工程组提交的具有基线的配置项,对该库的内容的变动需要按照配置项变更控制来进展,该库只有工程级的配置管理员和系统级的配置管理员才有权限进展Update/Commit;⏹静态库:主要用于保存工程的Release〔内部/外部〕版本,包括所有的配置项;该库主要由系统级配置管理员来控制;♦操作示意图♦存储构造把电子文档和源代码使用同一种方式来存储;在公司效劳器上建立一个专门存放配置库的目录,然后各个工程的配置库统一建立在其中;一般构造如下:Svn Database 〔Server Folder〕+ vss SF2021+ vss RAS+ vss ETEStatic Folder 〔Server Folder〕Bluten SF2021[Release ID1].rar[Release ID1].rar+ RAS+ ETE♦动态库〔Dynamic Lib〕、基线库〔Baseline Lib〕:⏹存储构造C:\share\Cmmi\PA\成型文件\配置管理\指⏹动态库:在Dynamic Lib下建立一个Documents和一个Sourcecode文件夹。
Documents下按照软件工程开发流程涉及到的过程域进展命名和建立存放构造;Sourcecode建立时只建立一个空的文件夹,剩余的由工程级配置管理员或工程经理创立;⏹基线库:分开发基线〔Develop baseline〕和产品基线〔Product Baseline〕开发基线的构造和动态库的构造一样;产品基线包含Install Program〔安装包源代码〕、Running Program〔可运行组件〕、Setup Disk 〔安装包〕⏹静态库:〔以操作系统文件目录构造存在〕工程名称***[Release ID1].rar[Release ID2].rar…♦库的建立动态库和基线库由配置管理员建立在公司效劳器上,存贮在SVN建立的库中;静态库由配置管理员在需要时在公司效劳器上,以文件方式存贮;♦Web工程源代码目录构造3. 配置管理配置项配置项识别的准那么及范围配置项类别入库时机备注工程工期个人预估表纸面立项过程完毕工程工期评估综合表纸面立项过程完毕评审会议记录纸面立项过程完毕工程工期评审需求纸面立项过程完毕立项文档电子&纸面立项过程完毕工程承诺书纸面立项过程完毕立项会议记录纸面立项过程完毕工程里程碑报告电子工程里程碑工程里程碑质量报告电子工程里程碑里程碑会议记录纸面工程里程碑工程月会会议记录纸面工程月会完毕工程总结报告电子工程结项会议之前根本配置项以下是公司的根本配置项列表,任何工程都必须包含这个列表中的配置项,其他配置项可以参考“配置项识别准那么〞或工程过程定义来增添。
VS中Debug和Realease、及静态库和动态库的区别整理

VS中Debug和Realease、及静态库和动态库的区别整理⼀、Debug和Realease区别产⽣的原因Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。
Release 称为发布版本,它往往是进⾏了各种优化,使得程序在代码⼤⼩和运⾏速度上都是最优的,以便⽤户很好地使⽤。
Debug 和 Release 的真正区别,在于⼀组编译选项。
Debug 版本参数含义/MDd /MLd 或 /MTd 使⽤ Debug runtime library(调试版本的运⾏时刻函数库)/Od 关闭优化开关/D "_DEBUG" 相当于 #define _DEBUG,打开编译调试代码开关(主要针对assert函数)/ZI创建 Edit and continue(编辑继续)数据库,这样在调试过程中如果修改了源代码不需重新编译GZ 可以帮助捕获内存错误Release 版本参数含义/MD /ML 或 /MT 使⽤发布版本的运⾏时刻函数库/O1 或 /O2 优化开关,使程序最⼩或最快/D "NDEBUG" 关闭条件编译调试代码开关(即不编译assert函数)/GF 合并重复的字符串,并将字符串常量放到只读内存,防⽌被修改Debug 和 Release 并没有本质的界限,他们只是⼀组编译选项的集合,编译器只是按照预定的选项⾏动。
⼆、Debug和Realease区别的表现I. 内存分配问题1. 变量未初始化。
下⾯的程序在debug中运⾏的很好。
thing * search(thing * something)BOOL found;for(int i = 0; i < whatever.GetSize(); i++){if(whatever[i]->field == something->field){ /* found it /found = TRUE;break;} / found it */}if(found)return whatever[i];elsereturn NULL;⽽在release中却不⾏,因为debug中会⾃动给变量初始化found=FALSE,⽽在release版中则不会。
头文件和库文件-静态库和动态库

头⽂件和库⽂件-静态库和动态库⼀、头⽂件和库⽂件头⽂件提供声明,库⽂件提供定义/实现。
C代码的编译过程: 预处理(需要头⽂件) -> 编译 -> 汇编 -> 链接(需要库⽂件); 执⾏时可能还有动态链接过程。
编译的时候,只要有头⽂件中的声明就⾜够了。
在链接的时候,把已经编译好的.obj和现有的.lib⽂件进⾏链接,这时就可以最终⽣成可执⾏⽂件了。
其实头⽂件与其实现⽂件或相应lib⽂件都没有直接的联系。
头⽂件是告诉编译器函数是如何去调⽤如何返回的,所有实现都是分别编译,最后在链接阶段链在⼀起。
头⽂件包含声明, 库⽂件包含实现或者与DLL库的连接所以,如果在代码⾥要⽤到这些函数那么就要包含头⽂件,编译的时候才能知道这些函数的原形;在进⾏代码连接的时候就需要库⽂件了,这时连接器就把函数的实现代码(静态库)连接到你的程序或者将你的函数调⽤连接到相应的DLL的对应函数(动态库)lib是静态库, 编译的时候代码直接插⼊到你的程序 ,DLL是动态库,编译的时候,只是产⽣⼀些调⽤DLL内代码的导⼊表,真正运⾏的时候是调⽤的DLL内的代码。
总结起来就是,库⽂件通过头⽂件向外导出接⼝。
⽤户通过头⽂件找到库⽂件中函数实现的代码从⽽把这段代码链接到⽤户程序中去。
.a代表传统的静态函数库(也称作归档⽂件:archive).so代表共享函数库⼆、创建静态库⽂件:1.创建源⽂件willku1.c和willku2.c2.编译源⽂件⽣成.o⽂件(将要包含在库⽂件中的⽬标⽂件)gcc -c willku1.c willku2.c =>willku1.o willku2.o3.创建头⽂件ishead.h内容:void willku1(char *);void willku2(int);4.创建应⽤程序app.c(将调⽤willku2.c⽂件)#include "ishead.h"5.编译、测试应⽤程序app.cgcc -c app.cgcc -o app app.o willku2.o./app6.创建并使⽤库⽂件(.a),使⽤ar创建归档⽂件并将⽬标⽂件加进去。
gcc生成静态库和动态库

gcc生成静态库和动态库一、库文件简介简单地说,库(Library)就是一组已经写好了的函数和变量、经过编译代码,是为了能够提高开发效率和运行效率而设计的。
库分为静态库(Static Library)和共享库(Shared library)两类。
静态库文件的扩展名是.a,共享库文件的扩展名是.so(在CYGWIN环境下,分别叫做.o和.dll)。
共享库现在常常被叫做动态库,是由于很多人借用了MS Windows的DLL(Dynamic Linked Library)这个词。
(1)静态库静态是指每个用到该库的应用程序都拥有一份自己的库拷贝;应用程序运行的时候,即使将库删除也没有问题,因为应用程序自己已经有了自己的拷贝。
(2)共享库一个共享库有可能被多个所有应用程序共享。
因此,对每个应用程序来说,即使不再使用某个共享库,也不应将其删除。
此外,应用程序需要正确的环境变量设置(LD_LIBRARY_PATH),从而找到共享库所在的位置,否则,应用程序运行时会报告找不到这个库。
二、关于使用库的问题如果库是已经编译好的,那么如何在开发、运行应用程序时使用呢?头文件和库文件所在的路径,必须通过适当的方式通知给编译器、链接器和相关的应用程序。
对于静态库来说,主要涉及开发工具,如gcc。
例如,用gcc编译、链接时,需要通过适当的路径找到头文件和静态库文件;实现的方法有两种:gcc的命令行参数(-I, -L)shell的环境变量(C_INCLUDE_PATH, LIBRARY_PATH对于共享库来说,程序在运行时,如果用到了动态库,也需要找到对应的动态库文件;实现的方法:shell的环境变量(LD_LIBRARY_PATH)1) gcc命令行参数(-I, -L)默认情况下,gcc会自动搜索下面的路径:对头文件:/usr/local/include//usr/include/对库文件:/usr/local/lib//usr/lib/但是由于系统管理员对系统安装路径有不同的配置,或者对于如64位系统等情况,上述路径对于一台具体的计算机来说可能不同。
QT开发——动态库静态库的生成与调用(Qmake和Cmake方式)

QT开发——动态库静态库的⽣成与调⽤(Qmake和Cmake⽅式)1.理解动态库与静态库区别链接:https:///wonengguwozai/article/details/93195827静态库和动态库最本质的区别就是:该库是否被编译进⽬标(程序)内部。
1.1 静态(函数)库⼀般扩展名为(.a或.lib),这类的函数库通常扩展名为libxxx.a或xxx.lib 。
这类库在编译的时候会直接整合到⽬标程序中,所以利⽤静态函数库编译成的⽂件会⽐较⼤,这类函数库最⼤的优点就是编译成功的可执⾏⽂件可以独⽴运⾏,⽽不再需要向外部要求读取函数库的内容;但是从升级难易度来看明显没有优势,如果函数库更新,需要重新编译。
1.2 动态函数库动态函数库的扩展名⼀般为(.so或.dll),这类函数库通常名为libxxx.so或xxx.dll 。
与静态函数库被整个捕捉到程序中不同,动态函数库在编译的时候,在程序⾥只有⼀个“指向”的位置⽽已,也就是说当可执⾏⽂件需要使⽤到函数库的机制时,程序才会去读取函数库来使⽤;也就是说可执⾏⽂件⽆法单独运⾏。
这样从产品功能升级⾓度⽅便升级,只要替换对应动态库即可,不必重新编译整个可执⾏⽂件。
1.3总结从产品化的⾓度,发布的算法库或功能库尽量使动态库,这样⽅便更新和升级,不必重新编译整个可执⾏⽂件,只需新版本动态库替换掉旧动态库即可。
从函数库集成的⾓度,若要将发布的所有⼦库(不⽌⼀个)集成为⼀个动态库向外提供接⼝,那么就需要将所有⼦库编译为静态库,这样所有⼦库就可以全部编译进⽬标动态库中,由最终的⼀个集成库向外提供功能。
2.qmake⽅式⽣成和调⽤动态/静态库链接:https:///lywzgzl/article/details/428059912.1 ⽣成库QT -= guiTARGET = laser_libTEMPLATE = libCONFIG += staticlib #加这句是⽣成静态库,不加则是动态库DEFINES += LASER_LIB_LIBRARYDEFINES += QT_DEPRECATED_WARNINGSLIBS += /usr/lib/x86_64-linux-gnu/libboost_thread.so\/usr/lib/x86_64-linux-gnu/libboost_system.soSOURCES += \laser_lib.cppHEADERS += \laser_lib.h \laser_lib_global.hinclude(LMS1xx/LMS1xx.pri)DESTDIR = $$PWD/../Libunix {target.path = /usr/libINSTALLS += target}2.2 调⽤库QT -= guiCONFIG += c++11 consoleCONFIG -= app_bundleDEFINES += QT_DEPRECATED_WARNINGS#增加系统库的依赖LIBS +=/usr/lib/x86_64-linux-gnu/libboost_thread.so\/usr/lib/x86_64-linux-gnu/libboost_system.so#增加⾃定义库的依赖LIBS += -L$$PWD/../Lib -llaser_lib #$$PWD获取当前pro⽂件的⽬录INCLUDEPATH += ../laser_libSOURCES += main.cppDESTDIR = $$PWD/../Lib3.cmake⽅式⽣成和调⽤动态库3.1创建共享库项⽬Cmake新建⼀个Qt Creator项⽬,在CMakeLists.txt中添加如下代码#-------------------------------------- 搜索软件包 --------------------------------------find_package(Qt5Widgets REQUIRED)find_package(Qt5Network REQUIRED)set(CMAKE_AUTOMOC ON)#-------------------------------------- 包含头⽂件 --------------------------------------include_directories(${Qt5Widgets_INCLUDE_DIRS})include_directories(${Qt5Network_INCLUDE_DIRS})include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)#-------------------------------------- -添加项⽬- --------------------------------------FILE(GLOB_RECURSE HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.h*)FILE(GLOB_RECURSE SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.c*)add_library(${PROJECT_NAME} SHARED${HEADER_FILES}${SOURCE_FILES}) #STATIC or SHARED 对应静态库或者动态库target_link_libraries(${PROJECT_NAME}${Qt5Widgets_LIBRARIES}${Qt5Network_LIBRARIES})#-------------------------------------- -设置输出- --------------------------------------set(OUTPUT_LIB_DIR ${PROJECT_BINARY_DIR}/libCACHE PATH "Output directory for libraries")file(MAKE_DIRECTORY ${OUTPUT_LIB_DIR})file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/${PROJECT_NAME})set(LIBRARY_OUTPUT_PATH ${OUTPUT_LIB_DIR})#-------------------------------------- -安装项⽬- --------------------------------------install(TARGETS ${PROJECT_NAME}EXPORT ${PROJECT_NAME}LIBRARY DESTINATION ${LIBRARY_OUTPUT_PATH})按需编辑plugintest.h和plugintest.cpp,这个就是该共享库项⽬的plugintest类了,我加⼊了⼀个int sum(int input1, int input2);公共函数,内容为:int Plugintest::sum(int input1, int input2){std::cout<<"Hello World!"<<std::endl;int sum = input1+input2;return sum;}保存并编译项⽬吧,没问题的话会在plugintest-build/lib⽬录⾥⽣成libplugintest.so。
lib静态库与动态库

先删除 除.c和.h外的 所有文件,恢复成我们刚刚编辑完举例程序状态。
# rm -f hello hello.o /usr/lib/libmyhello.so
# ls
hello.c hello.h main.c
#
在来创建静态库文件libmyhello.a和动态库文件libmyhello.so。
#
我们删除静态库文件试试公用函数hello是否真的连接到目标文件 hello中了。
# rm libmyhello.a
rm: remove regular file `libmyhello.a'? y
# ./hello
Hello everyone!
#
程序照常运行,静态库中的公用函数已经连接到目标文件中了。
7.可执行程序在执行的时候如何定位共享库文件
当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径
此时就需要系统动态载入器(dynamic linker/loader)
对于elf格式的可执行程序,是由ld-linux.so*来完成的,它先后搜索elf文件的 DT_RPATH段—环境变量LD_LIBRARY_PATH—/etc/ld.so.cache文件列表—/lib/,/usr/lib目录找到库文件后将其载入内存
# mv libmyhello.so /usr/lib
# ./hello
./hello: error while loading shared libraries: /usr/lib/libhello.so: cannot restore segment prot after reloc: Permission denied
1.什么是库
在windows平台和linux平台下都大量存在着库。
动态链接库及静态链接库(windows下的.dll.lib和linux下的.so.a)

动态链接库及静态链接库(window s下的.dll .lib和li nux下的.so .a)库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀。
例如:libhel lo.so libhel lo.a 为了在同一系统中使用不同版本的库,可以在库文件名后加上版本号为后缀,例如:libhel lo.so.1.0,由于程序连接默认以.so为文件后缀名。
所以为了使用这些库,通常使用建立符号连接的方式。
ln -s libhel lo.so.1.0 libhel lo.so.1ln -s libhel lo.so.1 libhel lo.so使用库当要使用静态的程序库时,连接器会找出程序所需的函数,然后将它们拷贝到执行文件,由于这种拷贝是完整的,所以一旦连接成功,静态程序库也就不再需要了。
然而,对动态库而言,就不是这样。
动态库会在执行程序内留下一个标记…指明当程序执行时,首先必须载入这个库。
由于动态库节省空间,linux下进行连接的缺省操作是首先连接动态库,也就是说,如果同时存在静态和动态库,不特别指定的话,将与动态库相连接。
现在假设有一个叫hel lo的程序开发包,它提供一个静态库lib hello.a 一个动态库l ibhel lo.so,一个头文件h ello.h,头文件中提供sayhe llo()这个函数/* hello.h */void sayhel lo();另外还有一些说明文档。
这一个典型的程序开发包结构1.与动态库连接linux默认的就是与动态库连接,下面这段程序testl ib.c使用hel lo库中的sayhe llo()函数/*testli b.c*/#includ e#includ eint main(){sayhel lo();return 0;}使用如下命令进行编译$gcc -c testli b.c -o testli b.o用如下命令连接:$gcc testli b.o -lhello -o testli b在连接时要注意,假设libh ello.o 和libhe llo.a都在缺省的库搜索路径下/usr/lib下,如果在其它位置要加上-L参数与与静态库连接麻烦一些,主要是参数问题。
库技术 - Linux库详解

Linux库详解1 库基本概念1。
1 库的分类有两种说法,如果熟悉WIN平台下的DLL,相信不难理解:库可以有三种使用的形式:静态、共享和动态.静态库的代码在编译时就已连接到开发人员开发的应用程序中,而共享库只是在程序开始运行时才载入,在编译时,只是简单地指定需要使用的库函数。
动态库则是共享库的另一种变化形式.动态库也是在程序运行时载入,但与共享库不同的是,使用的库函数不是在程序运行开始,而是在程序中的语句需要使用该函数时才载入。
动态库可以在程序运行期间释放动态库所占用的内存,腾出空间供其它程序使用。
由于共享库和动态库并没有在程序中包括库函数的内容,只是包含了对库函数的引用,因此代码的规模比较小。
Linux下的库文件分为共享库和静态库两大类,它们两者的差别仅在程序执行时所需的代码是在运行时动态加载的,还是在编译时静态加载的。
区分库类型最好的方法是看它们的文件后缀,通常共享库以.so(Shared Object的缩写)结尾,静态链接库通常以。
a 结尾(Archive的缩写)。
在终端缺省情况下,共享库通常为绿色,而静态库为黑色。
已经开发的大多数库都采取共享库的方式。
ELF格式的可执行文件使得共享库能够比较容易地实现,当然使用旧的a.out模式也可以实现库的共享。
Linux系统中目前可执行文件的标准格式为ELF格式。
.a的是为了支持较老的a。
out格式的可执行文件的.so的是支持elf格式的可执行文件的库。
.a是静态库文件,可以用ar 命令生成.。
so是动态库文件,编译时加上指定的选项即可生成,具体选项看相应的系统文档了.1.2 库的命名规则GNU库的使用必须遵守Library GNU Public License(LGPL许可协议)。
该协议与GNU许可协议略有不同,开发人员可以免费使用GNU库进行软件开发,但必须保证向用户提供所用的库函数的源代码.库的命名和约定:(1)所以的库都以lib开头,许多开发工具都依赖这个约定,特别是GCC,它会在—l选项所指定的文件名前自动地插入lib。
- 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。