静态库与动态库的基础知识手册
静态库和动态库编译
静态库和动态库编译静态库和动态库是编程中常用的两种库文件形式,本文将介绍它们的编译过程和使用方法。
1. 静态库编译静态库是一种在编译时被链接到程序中的库文件,它包含了程序所依赖的所有函数和数据结构,因此程序在运行时不需要再加载库文件。
静态库的编译过程包括以下步骤:(1)创建一个或多个源文件,使用编译器将它们编译成目标文件(.o 或 .obj)。
(2)将多个目标文件打包成一个静态库文件,通常使用 ar 工具完成此操作。
例如,在 Linux 系统下,可以使用以下命令创建名为 libfoo.a 的静态库文件:$ ar rcs libfoo.a foo1.o foo2.o ...其中,rcs 参数分别表示创建、向库文件中添加目标文件和生成索引表。
(3)在编译器中使用静态库,需要将其链接到目标程序中。
在Linux 系统下,可以使用以下命令编译名为 main.c 的源文件和名为libfoo.a 的静态库文件:$ gcc -o main main.c -L. -lfoo其中,-L 参数指定库文件搜索路径,. 表示当前目录;-l 参数指定链接库文件,实际上是将其前缀 lib 和后缀 .a 去掉,即 foo。
2. 动态库编译动态库是一种在程序运行时动态加载的库文件,它只包含程序所需要的部分函数和数据结构,因此可以减小程序的尺寸和加载时间。
动态库的编译过程包括以下步骤:(1)创建一个或多个源文件,使用编译器将它们编译成目标文件。
(2)将多个目标文件打包成一个共享库文件,通常使用 ld 或链接器完成此操作。
例如,在 Linux 系统下,可以使用以下命令创建名为 libfoo.so 的动态库文件:$ gcc -shared -o libfoo.so foo1.o foo2.o ...其中,-shared 参数表示生成共享库文件。
(3)在编译器中使用动态库,需要将其链接到目标程序中。
在Linux 系统下,可以使用以下命令编译名为 main.c 的源文件和名为libfoo.so 的动态库文件:$ gcc -o main main.c -L. -lfoo其中,-L 和 -l 参数的含义同静态库。
动态库与静态库的异同
动态库与静态库的异同、生成和使用详解
分类:基于Linux的C/C++程序开发2012-12-05 11:11 501人阅读评论(0) 收藏举报生成和调用静态库与动态库静态库与动态库的区别静态库和动态库
下面表格实例中,实现了把test模块分别生成动态库(libtest.so)和静态库(libtest.a),并使用了生成的库。
详情和注解如下:
注解:
test.c -----测试功能模块的c文件
test.h -----测试功能模块的头文件
main.c -----include“test.h”的主函数文件
-share -----该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。
相当于一个可执行文件。
-fPCI -----表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不
能达到真正代码段共享的目的。
注解A:在使用到这些公用函数的源程序中包含这些公用函数的原型声明,然后在用gcc 命令生成目标文件时指明静态库名,gcc 将会从静态库中
将公用函数连接到目标文件中。
注意,gcc 会在静态库名前加上前缀lib,然后追加扩展名.a 得到的静态库文件名来查找静态库文件。
C语言动态库与静态库区别
C语言动态库与静态库区别在C语言开发中,库(Library)是一种可重用的代码模块,它包含了一系列已经编译的函数和数据,用于帮助开发人员快速完成特定的任务。
库分为动态库和静态库两种形式,它们在使用方式和编译过程中存在一些显著的区别。
一、动态库(Dynamic Library)动态库也被称为共享库(Shared Library),其扩展名一般为“.so”(在Windows系统下为“.dll”)。
动态库在程序运行时被加载到内存,可以被多个程序实例共享,使得内存利用率更高。
而且,由于动态库在编译时并未与目标程序绑定,因此可以通过动态链接器在程序运行时加载、卸载和更新,具有更高的灵活性。
动态库的特点如下:1. 内存占用:动态库在程序运行时才会被加载到内存,因此不会增加目标程序的体积。
多个程序实例可以共享同一个动态库,节省内存空间。
2. 更新维护:对于动态库的更新和维护,只需要替换库文件即可,无需重新编译目标程序。
3. 运行时加载:动态库的加载和卸载是在程序运行时完成的,可以根据需要进行动态加载和卸载,提高程序的灵活性。
4. 共享性:多个程序实例可以同时使用同一个动态库,提高代码的重用性,并且减少了库文件的重复。
二、静态库(Static Library)静态库是在编译目标程序时,将库的代码和数据直接复制到目标程序中。
静态库的文件扩展名通常为“.a”(在Windows系统下为“.lib”)。
由于静态库在编译时与目标程序绑定,因此静态库的代码和数据会被完整复制到每一个使用该库的程序中。
静态库的特点如下:1. 执行速度:由于静态库的代码和数据完全被复制到了目标程序中,因此在执行过程中不需要进行动态加载,执行速度相对较快。
2. 独立性:每一个使用该库的程序都包含了静态库的完整副本,因此静态库程序可以独立运行,无需依赖其他库文件。
3. 目标文件较大:由于静态库代码和数据完全被复制到目标程序中,所以会导致目标文件体积较大。
头文件和库文件-静态库和动态库
头⽂件和库⽂件-静态库和动态库⼀、头⽂件和库⽂件头⽂件提供声明,库⽂件提供定义/实现。
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创建归档⽂件并将⽬标⽂件加进去。
linux静态库与动态库
linux 静态库、共享库一、什么是库本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。
由于windows和linux的本质不同,因此二者库的二进制是不兼容的。
Linux操作系统支持的函数库分为静态库和动态库,动态库又称共享库。
Linux 系统有几个重要的目录存放相应的函数库,如/lib /usr/lib。
二、静态函数库、动态函数库A. 这类库的名字一般是libxxx.a;利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进可执行文件了。
当然这也会称为它的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译,而且体积也较大。
B.这类库德名字一般是libxxx.so,动态库又称共享库;相对于静态函数库,动态函数库在编译的时候并没有被编译进目标代码中,你的程序执行到相关函数时才调用函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。
由于函数库没有被整合进你的程序,而是程序运行时动态申请并调用,所以程序的运行环境中必须提供相应的库。
动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。
而且如果多个应用程序都要使用同一函数库,动态库就非常适合,可以减少应用程序的体积。
注意:不管是静态函数库还是动态函数库,都是由*.o目标文件生成。
三、函数库的创建A.静态函数库的创建ar -cr libname.a test1.o test2.oar:静态函数库创建的命令-c :create的意思-r :replace的意思,表示当前插入的模块名已经在库中存在,则替换同名的模块。
如果若干模块中有一个模块在库中不存在,ar显示一个错误信息,并不替换其他同名的模块。
默认的情况下,新的成员增加在库德结尾处。
B.动态函数库的创建gcc -shared -fpic -o libname.so test1.c test2.c-fpic:产生代码位置无关代码-shared :生成共享库四、静态库和动态库的使用案例:add.c#include <stdio.h>int add(int a,int b){return a + b;}sub.c#include <stdio.h>int sub(int a,int b){return a - b;}head.h#ifndef _HEAD_H_#define _HEAD_H_extern int add(int a,int b); extern int sub(int a,int b); #endifmain.c#include <stdio.h>int main(int argc,char *argv[]){int a,b;if(argc < 3){fprintf(stderr,"Usage : %s argv[1] argv[2].\n",argv[0]);return -1;}a = atoi(argv[1]);b = atoi(argv[2]);printf("a + b = %d\n",add(a,b));printf("a - b = %d\n",sub(a,b));return 0;}生成静态库生成动态库:使用生成的生成的库:其中-L 指定函数库查找的位置,注意L后面还有'.',表示在当前目录下查找-l则指定函数库名,其中的lib和.a(.so)省略。
关于静态链接库(Lib)与动态链接库(DLL)
关于静态链接库(Lib)与动态链接库(DLL)静态链接库(Lib)和动态链接库(DLL)的问题困扰了我很长时间,而当中关键的问题是两者有何联系?又有何区别呢?怎么创建?怎么使用?使用的过程中要注意什么?一直想把这个问题总结一下。
在windows下一般可以看到后缀为dll和后缀为lib的文件,但这两种文件可以分为三种库,分别是动态链接库(Dyna mic-Link Libraries),目标库(Object Li braries)和导入库(Import Libra ries),下面一一解释这三种库。
目标库(Object Li braries)目标库又叫静态链接库,是扩展名为.LIB的文件,包括了用户程序要用到的各种函数。
它在用户程序进行链接时,“静态链接”到可执行程序文件当中。
例如,在V C++中最常使用到的C运行时目标库文件就是LIB C.LIB。
在链接应用程序时常使用所谓“静态链接”的方法,即将各个目标文件(.obj)、运行时函数库(.lib)以及已编译的资源文件(.res)链接到一起,形成一个可执行文件(.exe)。
使用静态链接时,可执行文件需要使用的各种函数和资源都已包含到文件中。
这样做的缺点是对于多个程序都使用的相同函数和资源要重复链接到exe文件中,使程序变大、占用内存增加。
导入库(I mport Li braries)导入库是一种特殊形式的目标库文件形式。
和目标库文件一样,导入库文件的扩展名也是.LIB,也是在用户程序被链接时,被“静态链接”到可执行文件当中。
但是不同的是,导入库文件中并不包含有程序代码。
相应的,它包含了相关的链接信息,帮助应用程序在可执行文件中建立起正确的对应于动态链接库的重定向表。
比如KERNEL32.LIB、USER32.LIB和GDI32.LIB就是我们常用到的导入库,通过它们,我们就可以调用Windows提供的函数了。
如果我们在程序中使用到了Rec tangle这个函数,GDI32.LIB就可以告诉链接器,这个函数在GDI32.DLL动态链接库文件中。
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平台下都大量存在着库。
动态库&静态库
}
return 0;
}
end====================================================
下面是测试程序的 makefile
begin====================================================
//声明函数
int w_log(char *str);
#endif
end=====================================================
下面是all.h 中w_log 函数的实现
begin=====================================================
1)$gcc -fPIC -o libtest.o -c lib_test.c
2)$gcc -shared -o libtest.so libtest.o
也可以直接使用一条命令gcc -fPIC -shared -o libtest.so lib_test.c
动态库调用方式一:
下面就是静态调用刚才生成的 libcommonso.so 动态库了
以下是测试程序:
begin=====================================================
//./test.c
int main(int argc, char *argv[])
4) 使用静态链接库
$nm libtest.a //nm工具可以打印出库中的涉及到的所有符号,库既可以是静态的也可以是动态的。nm列出的符号有很多, 常见的有三种,一种是在库中被
动态库和静态库
gcc -o main -Ldir -ltest main.c
查看动态库
在库文件夹下,可以查看动态库文件的依赖 关系
#ldd libadd.so
在当前文件夹下可以查看可执行文件的信息
#file hello 可以看hello文件使用的是动态库
创建库示例
/*main.c*/ #include<stdio.h> main() { int x=5; int y=6; printf(“x+y=%d\n”,add(x,y)); }
共享库:编译时,只是在生成的可执行程序中简 单的指定需要使用的库函数信息,程序运行过程 中需要利用库函数。
动态库:共享库的一种变化形式,目前大多采用 共享库的方式。
函数库分类
也就是说: 静态库在程序编译时会被连接到目标代码中,程
序运行时将不再需要该静态库。 动态库在程序编译时并不会被连接到目标代码中,
创建库示例
/*add.c*/ add(int x,int y) { int result; result=x+y; return result; }
创建静态库示例
1. #gcc add.c -c -o add.o //生成一 个二进制内容的.o文件,只进行前三步编译
2. #ar -cr libadd.a add.o //静态库 生成了,而且文件名必须以lib开头
#LD_LIBRARY_PATH=$PWD #export LD_LIBRARY_PATH
编译时指定路径
#gcc -o cacul -Wl,-rpath,. -L -lalg caculation.c
3. #gcc main.c -L. –ladd -static o ok //把库文件和.o文件生成可执行文 件ok
静态库和动态库
8月27号回顾:Linux Unix的简介gcc 的用法预处理命令今天:静态库和共享库(动态库)C语言的错误处理环境变量在程序中的处理(环境表)由于项目比较复杂,代码数量非常庞大,可以把代码打包成库文件,提供库文件和头文件即可。
库文件分成两种:静态库和共享库(动态库),静态库和共享库都是代码的归档文件。
在使用静态库时,把静态库复制到目标文件中,导致目标文件比较大;使用共享库时,把函数的地址放到目标文件中。
静态库和共享库的优缺点:静态库的优点:目标文件是独立于库文件,运行速度稍快。
缺点:目标文件太大,不利于代码的修改,扩展和复用共享库的优点:目标文件比较小,修改,扩展和复用比较方便。
缺点:目标文件必须和共享库文件同时存在,代码才能正常运行。
运行速度稍慢。
开发多半使用共享库。
使用了静态库的步骤:一.创建静态库文件(.a)1写源程序add.c保存退出2编译源文件,得到.o文件(gcc -c)3创建静态库文件:ar -r libXX.a add.o //把add.o文件加入到libxx.a库中注:lib 开头.a结束是静态库的命名规范,XX叫库名创建静态库文件后,还需要提供.h文件。
二.使用静态库1写调用源程序text.c ,保存退出2编译text.c ,只编译不连接(gcc -c)3连接text.o 和静态库文件连接方式有三种:A直接连接gcc text.o libXX.aB 配置环境变量LIBRARY_PA TH,把库文件所在路径放入其中,然后:gcc text.o -lXXC gcc text.o -lXX -L所在路径(双L,推荐)自己总结:写.c文件(add.c)编译不连接gcc -c 得到.o 文件(add.o)创建库文件ar -r libXX.a add.o写调用的源程序.c 文件(text.c)编译不连接gcc -c text.c 得到.o文件(text.o)连接text.o和静态库gcc text.o libXX.a运行产生的a.out文件使用共享库的步骤:一.创建共享库1写源程序add.c ,保存退出2编译gcc -c -fpic add.c (不写-fpic也行)3生成共享库gcc -shared add.o -olibXX.so注:共享库也需要提供头文件二.使用共享库和静态库方式一样注:连接成功后。
动态链接库(dll)和静态库的创建及使用教程
动态链接库和静态库的创建及使用教程第一部分静态库(以vs2005为例)一、创建新的静态库项目1.从“文件”菜单中,选择“新建”,然后选择“项目…”。
2.从“项目类型”窗格中,选择“Visual C++”下的“Win32”。
3.从“模板”窗格中,选择“Win32 控制台应用程序”。
4.为项目选择一个名称,如“MathFuncsLib”,并将其输入“名称”字段。
为解决方案选择一个名称,如“StaticLibrary”,并将其输入“解决方案名称”字段。
5.按“确定”启动Win32 应用程序向导。
在“Win32 应用程序向导”对话框的“概述”页中,按“下一步”。
6.从“Win32 应用程序向导”的“应用程序设置”页中,选择“应用程序类型”下的“静态库”。
7.从“Win32 应用程序向导”的“应用程序设置”页中,取消选择“附加选项”下的“预编译头”。
8.按“完成”创建项目。
向静态库添加类1.若要为新类创建头文件,请从“项目”菜单中选择“添加新项…”。
将显示“添加新项”对话框。
从“类别”窗格中,选择“Visual C++”下的“代码”。
从“模板”窗格中选择“头文件(.h)”。
为头文件选择一个名称,如“MathFuncsLib.h”,并按“添加”。
将显示一个空白文件。
2.添加一个名为“MyMathFuncs”的简单类,以执行常见的算术运算,如加、减、乘和除。
代码应与以下内容类似:// MathFuncsLib.hnamespace MathFuncs{class MyMathFuncs{public:// Returns a + bstatic double Add(double a, double b);// Returns a - bstatic double Subtract(double a, double b);// Returns a * bstatic double Multiply(double a, double b);// Returns a / b// Throws DivideByZeroException if b is 0static double Divide(double a, double b);};}3.若要为新类创建源文件,请从“项目”菜单中选择“添加新项…”。
c语言中库的定义等相关概念 -回复
c语言中库的定义等相关概念-回复C语言中的库(Library)是指一组预先编写好的可重用的代码,这些代码包含了各种功能,如输入输出、字符串处理、数学运算等。
库可以被其他程序调用,以提高开发效率和代码复用性。
本文将逐步解释库的定义,库的类型,库的使用和实现等相关概念。
定义:库是一种软件资源,其中包含了预先编写好的可重用的代码。
这些代码经过测试和优化,以提供特定功能或解决特定问题。
库可以作为单个文件或多个文件的集合提供。
C语言中的库分为两种类型:静态库和动态库。
库的类型:1. 静态库(Static Library):静态库也称为静态链接库,它在编译时被链接到可执行文件中。
静态库包含了预编译好的目标代码,这些代码可以直接在编译阶段与程序的其他模块进行链接。
静态库的优点是可移植性强,不依赖于特定的运行环境。
然而,静态库的缺点是占用磁盘空间较大,每个可执行文件都会包含一份完整的库代码。
2. 动态库(Dynamic Library):动态库也称为共享库或动态链接库,它在程序运行时被加载到内存中。
动态库的代码可以被多个程序共享,从而节省了系统资源。
动态库的优点是占用磁盘空间较小,可以在运行时动态加载和卸载。
然而,动态库的缺点是可能会导致版本兼容性问题和依赖关系管理较为复杂。
库的使用:使用库的步骤如下:1. 引入头文件(Include Header File):在需要使用库中函数或变量的源代码文件中,通过#include指令包含库的头文件。
头文件包含了库中函数和变量的声明。
示例代码如下:c#include <stdio.h>2. 链接库文件(Link Library File):在编译可执行文件时,需要将库的目标代码与程序的其他模块进行链接。
对于静态库,可以使用编译器提供的静态链接选项进行链接。
对于动态库,可以使用编译器提供的动态链接选项进行链接。
示例代码如下:gcc main.c -lmath 链接静态库gcc main.c -lmath 链接动态库3. 调用库中的函数(Call Functions):在源代码文件中,可以通过函数名直接调用库中的函数,并传递参数。
C++静态库与动态库深入研究——动态库篇!
C++静态库与动态库深⼊研究——动态库篇!⼀、动态库通过之前静态库那篇⽂章的介绍。
发现静态库更容易使⽤和理解,也达到了代码复⽤的⽬的,那为什么还需要动态库呢?1、为什么还需要动态库?为什么需要动态库,其实也是静态库的特点导致。
▶空间浪费是静态库的⼀个问题。
▶另⼀个问题是静态库对程序的更新、部署和发布页会带来⿇烦。
如果静态库liba.lib更新了,所以使⽤它的应⽤程序都需要重新编译、发布给⽤户(对于玩家来说,可能是⼀个很⼩的改动,却导致整个程序重新下载,全量更新)。
动态库在程序编译时并不会被连接到⽬标代码中,⽽是在程序运⾏是才被载⼊。
不同的应⽤程序如果调⽤相同的库,那么在内存⾥只需要有⼀份该共享库的实例,规避了空间浪费问题。
动态库在程序运⾏是才被载⼊,也解决了静态库对程序的更新、部署和发布页会带来⿇烦。
⽤户只需要更新动态库即可,增量更新。
动态库特点总结:✪动态库把对⼀些库函数的链接载⼊推迟到程序运⾏的时期。
✪可以实现进程之间的资源共享。
(因此动态库也称为共享库)✪将⼀些程序升级变得简单。
✪甚⾄可以真正做到链接载⼊完全由程序员在程序代码中控制(显⽰调⽤)。
Window与Linux执⾏⽂件格式不同,在创建动态库的时候有⼀些差异。
✪在Windows系统下的执⾏⽂件格式是PE格式,动态库需要⼀个DllMain函数做出初始化的⼊⼝,通常在导出函数的声明时需要有_declspec(dllexport)关键字。
✪ Linux下gcc编译的执⾏⽂件默认是ELF格式,不需要初始化⼊⼝,亦不需要函数做特别的声明,编写⽐较⽅便。
与创建静态库不同的是,不需要打包⼯具(ar、lib.exe),直接使⽤编译器即可创建动态库。
2、Linux下创建与使⽤动态库linux动态库的命名规则为:动态链接库的名字形式为 libxxx.so,前缀是lib,后缀名为“.so”。
✪针对于实际库⽂件,每个共享库都有个特殊的名字“soname”。
c++静态库与动态库的区别
c++静态库与动态库的区别分类:C++2012-11-26 11:41 3621人阅读评论(1) 收藏举报如果对Linux下静态链接库和动态链接库感兴趣,请狂点击 -->你懂的一,概念1)静态链接库就是你使用的.lib文件,库中得代码最后需要连接到你的可执行文件中去,所以静态连接的可执行文件一般比较大一些。
使用方法1> 格式如:#pragma comment(lib,"XXX.lib")2> 针对开发环境:1、如果使用VC,可以在Project Setting-->Link中加入你的静态库,也可以直接把该.lib文件加入到你的工程中2、如果使用Visual Studio,位置在项目→配置属性→连接器→输入→附加依赖项中加入.lib文件构造方法在静态库情况下,函数和数据被编译进一个二进制文件(通常扩展名为*.lib),Visual C++的编译器在链接过程中将从静态库中恢复这些函数和数据并把他们和应用程序中的其他模块组合在一起生成可执行文件。
这个过程称为"静态链接",此时因为应用程序所需的全部内容都是从库中复制了出来,所以静态库本身并不需要与可执行文件一起发行。
编程使用:使用lib需注意两个文件:(1).h头文件,包含lib中说明输出的类或符号原型或数据结构。
应用程序调用lib时,需要将该文件包含入应用程序的源文件中。
(2).lib文件,见上面。
2)Dynamic Link Library 的缩写形式,DLL是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件。
动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。
函数的可执行代码位于一个 DLL 中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。
DLL 还有助于共享数据和资源。
多个应用程序可同时访问内存中单个DLL 副本的内容。
C静态库(lib)及动态库(dll)的创建及调用
C静态库(lib)及动态库(dll)的创建及调用一、静态库的创建及调用最近在编程序的时候,用到静态库和动态库的创建和调用,将自己的一些心得总结如下,希望对各位有所帮助,有不恰当之处欢迎评论留言。
静态库和动态库的区别可以参考博客:windows中静态库lib和动态dll的区别及使用方法_dxzysk的专栏-CSDN博客_动态dll和静态库的区别1、静态库的创建为了方便大家学习,从空项目进行演示,实现输入两个数求出两数之和及两数之差,本文使用VS2017编译器。
(1)创建空项目(2)新建头文件.h和源文件.cpp其中test工程为后面测试用工程,现在不用考虑。
(3)修改项目属性,将目标文件扩展名和配置类型均修改为.lib (4)在项目头文件testLib.h中编写代码方法一和方法二均可以生成和调用(5)源文件testLib.cpp代码编写(6)工程生成可以看到工程目录下生成了testLib.ib和testLib.pdb文件,代表静态库生成成功。
2、静态库的调用(1)为了方便演示,在静态库生成的同解决方案下创建测试工程test,本地创建的是控制台应用程序。
(2)创建完测试工程后,在test.cpp文件中编写静态库调用程序(3)将test工程设置为启动工程,编译运行,会出现报错(4)针对(3)出现的报错,需要在项目中引入静态库文件路径静态库生成工程和测试工程目录如下:引入静态库的相对路径再次编译就可以成功。
运行结果如下至此,静态库的创建及调用讲解结束。
二、动态库的创建及调用1、动态库的创建动态库的创建介绍两种方式:__declspec(dllexport)和.def文件导出。
1.1、动态库的创建(__declspec(dllexport))(1)同静态库一样创建空项目testDll,创建头文件和源文件(2)修改项目属性,将目标文件扩展名和配置类型均修改为.dll(3)修改项目头文件testDll.h,本文介绍三种dll库生成的方法动态生成库的关键字为__declspec(dllexport)方法一和方法二的区别就是标识符是否被定义,如果标识符TESTDLL被定义则重新定义标识符TESTDLLAPI,并使用重新定义的标识符进行函数导出;如果标识符TESTDLL未被定义,则使用当前定义的标识符进行函数导出。
动态库与静态库
动态库与静态库什么叫库?库(Library)说⽩了就是⼀段编译好的⼆进制代码,加上头⽂件就可以供别⼈使⽤。
⼀种情况是某些代码需要给别⼈使⽤,但是我们不希望别⼈看到源码,就需要以库的形式进⾏封装,只暴露出头⽂件。
另外⼀种情况是,对于某些不会进⾏⼤的改动的代码,我们想减少编译的时间,就可以把它打包成库,因为库是已经编译好的⼆进制了,编译的时候只需要 Link ⼀下,不会浪费编译时间。
静态库:静态库即静态链接库(Windows 下的 .lib,Linux 和 Mac 下的 .a)。
之所以叫做静态,是因为静态库在编译的时候会被直接拷贝⼀份,复制到⽬标程序⾥,这段代码在⽬标程序⾥就不会再改变了。
静态库的好处很明显,编译完成之后,库⽂件实际上就没有作⽤了。
⽬标程序没有外部依赖,直接就可以运⾏。
当然其缺点也很明显,就是会使⽤⽬标程序的体积增⼤。
动态库:动态库即动态链接库(Windows 下的 .dll,Linux 下的 .so,Mac 下的 .dylib)。
与静态库相反,动态库在编译时并不会被拷贝到⽬标程序中,⽬标程序中只会存储指向动态库的引⽤。
等到程序运⾏时,动态库才会被真正加载进来。
动态库的优点是,不需要拷贝到⽬标程序中,不会影响⽬标程序的体积,⽽且同⼀份库可以被多个程序使⽤(因为这个原因,动态库也被称作共享库)。
同时,编译时才载⼊的特性,也可以让我们随时对库进⾏替换,⽽不需要重新编译代码。
动态库带来的问题主要是,动态载⼊会带来⼀部分性能损失,使⽤动态库也会使得程序依赖于外部环境。
如果环境缺少动态库或者库的版本不正确,就会导致程序⽆法运⾏(Linux 下喜闻乐见的 lib notfound 错误)。
C语言静态库与动态库的区别[权威资料]
C语言静态库与动态库的区别本文档格式为WORD,感谢你的阅读。
最新最全的学术论文期刊文献年终总结年终报告工作总结个人总结述职报告实习报告单位总结演讲稿C语言静态库与动态库的区别静态库与动态库的区别是什么呢?一起来看看下面的相关内容吧!更多内容请关注!区别1:在目标文件链接成可执行文件阶段,库函数(库函数本身有一个代码段)链接进可执行文件(代码段)中,占了很大的内存空间。
而使用动态库时,只是在链接时做了一个printf的标记,当可执行程序运行时才会加载这段printf(从库路径中加载动态链接库.so文件),这样就节省了可执行程序的空间,只有在运行这段很短的时间会占用可执行程序的空间。
可以做个测试,写一个输出hello world的小程序,一般是Linux下gcc中是默认是使用动态库的,可以看到可执行程序a.out的大小只有7千多k,而使用静态库,链接后生成可执行程序时把printf也链接到了可执行程序中,这时候可执行程序就有700多K了。
区别2:使用动态库对库的依赖性太强,一般发布的话需要库文件(库文件要放在相应的库路径中)也发布。
、静态链接库对库的依赖性不会有那么强。
静态库就像房车,出门旅游不用依赖住房,但是房车占空间;动态库就像小车,出门旅游依赖要住酒店,但是小车省空间。
实际上使用动态库在运行的时候加载printf也会占用可执行程序,在运行时占用可执行程序的空间其实是跟静态库是一样的。
但是试想:一个可执行程序a.out中有多个文件(如a应用程序,b应用程序,c文件程序),a,b,c都需要调用printf。
使用静态库时,链接时就链接了三份printf,运行时就加载三份printf,产生多分副本,白白浪费内存。
而使用动态库时,链接时,只是将printf的标记链接进了可执行程序a,out,运行时printf只用加载一份,a调用时就是调用这一份printf,b调用时也是调用这一份printf。
-------这才是动态库相对于静态库真正的优势!【相关阅读】C语言与JAVA的区别C语言C语言是一门通用计算机编程语言,应用广泛。
动静态库的依赖关系
动静态库的依赖关系一、动态库的依赖关系动态库(Dynamic Link Library,简称DLL)是一种在程序运行时才加载的库文件,它可以被多个程序共享使用。
在编译阶段,动态库并不会被直接链接到可执行文件中,而是在程序运行时动态加载到内存中。
动态库的依赖关系主要体现在两个方面:一是动态库之间的相互依赖关系,二是可执行文件与动态库之间的依赖关系。
1. 动态库之间的相互依赖关系在某些情况下,一个动态库可能会依赖于其他的动态库,这种依赖关系可以通过动态库的导入表来实现。
导入表中记录了动态库所依赖的其他动态库的名称和函数入口地址,程序在运行时会根据导入表来动态加载所需的依赖库。
2. 可执行文件与动态库之间的依赖关系可执行文件与动态库之间的依赖关系主要体现在链接阶段。
编译器在链接可执行文件时,会将可执行文件中使用到的动态库的信息(如库的名称、函数入口地址等)记录在可执行文件的导入表中。
在程序运行时,操作系统会根据导入表的信息来加载相应的动态库。
二、静态库的依赖关系静态库(Static Library)是在编译阶段被链接到可执行文件中的库文件。
静态库的依赖关系主要体现在可执行文件与静态库之间的链接关系。
1. 可执行文件与静态库之间的链接关系在编译可执行文件时,编译器会将使用到的静态库的代码复制到可执行文件中,使得可执行文件包含了静态库的全部代码。
因此,可执行文件与静态库之间的依赖关系是静态的,不需要在运行时动态加载。
2. 静态库之间的相互依赖关系静态库之间的相互依赖关系主要体现在链接阶段。
当一个静态库中使用到了其他的静态库时,编译器会将被使用的静态库的代码复制到当前的静态库中,使得当前的静态库包含了所有依赖的代码。
三、动态库和静态库的应用场景动态库和静态库各有其适用的场景和优势。
1. 动态库的应用场景动态库主要适用于需要共享代码的场景,它可以被多个程序共享使用,减少了代码的重复编译和内存占用。
动态库的更新和维护也更加方便,只需要替换动态库文件即可,无需重新编译可执行文件。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
静态库与动态库的基础知识手册
相信学过计算机的同学知道静态库和共享库(动态库)这两个词吧!接下来我们一起来回顾一下吧!
C语言的错误处理
环境变量在程序中的处理(环境表)
由于项目比较复杂,代码数量非常庞大,可以把代码打包成库文件,提供库文件和头文件即可。
库文件分成两种:
静态库和共享库(动态库),静态库和共享库都是代码的归档文件。
在使用静态库时,把静态库复制到目标文件中,导致目标文件比较大;使用共享库时,把函数的地址放到目标文件中。
静态库和共享库的优缺点:
静态库的优点:目标文件是独立于库文件,运行速度稍快。
缺点:目标文件太大,不利于代码的修改,扩展和复用共享库的优点:目标文件比较小,修改,扩展和复用比较方便。
缺点:目标文件必须和共享库文件同时存在,代码才能正常运行。
运行速度
稍慢。
开发多半使用共享库。
使用了静态库的步骤:
一.创建静态库文件(.a)
1写源程序add.c保存退出
2编译源文件,得到.o文件(gcc -c)
3创建静态库文件:
ar -r libXX.a add.o //把add.o文件加入到libxx.a库中
注:lib 开头.a结束是静态库的命名规范,XX叫库名
创建静态库文件后,还需要提供.h文件。
二.使用静态库
1写调用源程序text.c ,保存退出
2编译text.c ,只编译不连接(gcc -c)
3连接text.o 和静态库文件
连接方式有三种:
A直接连接
gcc text.o libXX.a
B 配置环境变量LIBRARY_PATH,把库文件所在路径放入其中,然后:
gcc text.o -lXX
C gcc text.o -lXX -L所在路径(双L,推荐)
自己总结:
写.c文件(add.c)
编译不连接gcc -c 得到.o 文件(add.o)
创建库文件ar -r libXX.a add.o
写调用的源程序.c 文件(text.c)
编译不连接gcc -c text.c 得到.o文件(text.o)
连接text.o和静态库gcc text.o libXX.a
运行产生的a.out文件
使用共享库的步骤:
一.创建共享库
1写源程序add.c ,保存退出
2编译
gcc -c -fpic add.c (不写-fpic也行)
3生成共享库
gcc -shared add.o -olibXX.so
注:共享库也需要提供头文件
二.使用共享库
和静态库方式一样
注:连接成功后。
需要配置LD_LIBRARY_PATH才能运行成功。
自己总结:
写.c文件(add.c)
编译不连接gcc -c -fpic add.c 得到.o 文件(add.o)
生成共享库gcc -shared add.o -olibXX.so
写调用函数.c 文件(text.c)
编译不连接gcc -c text.c 得到.o文件(text.o)
连接text.o和共享库gcc text.o libXX.so
连接成功后。
需要配置LD_LIBRARY_PATH才能运行成功
export LD_LIBRARY_PATH=.
运行产生的a.out文件
ldd 命令可以查看使用的共享库。
动态调用共享库(动态编程)
代码在运行时才知道调用哪个函数,执行哪一段代码
相关的函数:
dlopen() dlsym() dlclose() 错误处理dlerror()
dlopen:打开共享库文件
dlclose:关闭共享库文件
dlsym:从一个打开的库文件中获得一个函数,返回函数指针
dlopen(参数1,参数2)第一个参数是共享库的文件名,第二个参数是加载方式:
RTLD_LAZY 是延时加载,open 是不加载,使用加载
RTLD_NOW open 文件的同时加载
返回库文件的首地址
错误处理
C程序没有异常,因此错误处理有自己的一套机制:
用返回值的不同体现错误:
1返回指针类型,一般用NULL 代表错误。
2返回int 类型,返回的数据不可能是-1,一般用-1代表错误。
3返回int 类型,但返回数据有可能是-1,用指针取数据,用返回-1代表错误,返回0代表正确。
4如果不需要考虑错误处理,返回值为void 。
以上四种情况都是一般用法(惯例),都有特殊情况。
当然了在学习的过程中,还是要偶一些练习的,实践是检验真理的唯一途径吗。
以下有几道练习:
写四个函数,实现代码和错误处理
1打印传入的字符串(4)
2测试传入字符串的值,如果不是error ,返回ok,如果是error,代表出错,处理函数的错误。
(1)
3返回0到10 的随机数,如果随机数是5,代表出错。
(2)
4求两个整数的最大值,如果想相等,代表出错(3)
C对于错误的处理提供了一个外部全局变量,三个函数:
#include<errno.h >
errno -----错误的编号,不包括错误的信息
strerror()--把错误编号转换成错误信息
perror()---自动找到错误编号并打印对应的错误信息
printf()----”%m”自动打印错误信息
最常用的的错误处理函数就是perror().
perror()允许传入一些附加信息,帮助程序员定位哪里出了错误
errno 是一个全局变量,可以直接使用。
使用方式:
成功不改变值,失败设置值。
不是所有的函数都是用errno 处理错误
环境变量和环境表
所有的环境变量在程序中可以通过环境表获取
环境表是一个全局变量,类型字符指针数组,获取方式:
extern char** environ;
environ 就是环境表的首地址,是全局变量。