简介
本质上都是可执行代码的二进制格式,可以被装入内存中执行。
分为静态库和动态库。
不同:
被载入的时刻不同
静态库在程序编译时被链接到目标代码中,目标程序运行时不再需要该库,
移植方便但体积大,浪费资源,可执行文件大。
动态库在程序运行时才被载入,可执行文件小。使得程序升级相对简单,
比如动态库更新,只需要更换动态链接库文件,不需要更换可执行文件。
选项-I(大写的i):
<>包含的头文件搜索顺序:首先在-I指定的路径中搜索所需的头文件,再去默认/usr/local/include中
最后去默认/usr/include中搜索
""包含的头文件搜索顺序:先在当前目录下搜索,再去-I指定的路径中搜索,
再去默认/usr/local/include中,最后去默认/usr/include中搜索
-include:指定头文件路径,在命令行中包含头文件
-l(小写的L):链接共享库,如 lm.out
-g:产生可供GDB调试用的可执行文件,稍大,不加则GDB看不见函数名、变量名只有内存地址
静态库
后缀为.a,在Linux下一般命名为libxxx.a
优点:
可执行文件最终运行时不在需要该库的支持,因为所有使用的函数已经编译进去了
创建:
使用ar 将各个.o文件组合在一起
(1)编辑源文件(.c或.cpp)
(2)通过gcc -c xxx.c或g++ -c xxx.cpp生成目标文件(.o)
(3)用ar归档目标文件,生成静态库(ar [csrtv] libxxx.a xx.o xx1.o …)常用crs
c:无论库是否存在,都创建一个库
s:创建目标文件索引,创建较大库时加快时间
r:在库中插入模块,同名替换
t:显示库中目标文件的名称(tv:名称+时间+大小)
使用:
方法一:配合静态库写一个头文件,文件里的内容就是提供给外面可以使用的函数、
变量或类的声明,然后在要调用静态库函数的文件中包含该头文件。
方法二:也可以在文件头部extern 想要用到的静态库函数 编译时加上 -L[库文件路径] -lxxx
//-lxxx:自动寻找libxxx.a
实例
1、编写静态库的cpp文件
2、g++ -c out.cpp 生成 out.o 文件
3、ar crs libout.a out.o 生成 静态库文件 libout.a
4、使用:
方法一:
a、编写静态库cpp文件对应的头文件//这里只有一个函数,简单写下
b、编写调用程序main.cpp//其中包含了静态库cpp文件对应的头文件
c、编译出可执行文件 g++ main.cpp -o main -L. -lout
//此处应当注意-L. -lout2放在后边,放在前边不行,亲测
方法二:
a、编写调用程序main.cpp //extern 想要用到的静态库函数
b、编译出可执行文件 g++ main.cpp -o main -L. -lout
动态库
又称为共享库,后缀为.so,在Linux下一般命名为libxxx.M.N.so //M为主版本号,N为副版本号
默认首先链接同名动态库,找不到再找同名静态库
创建:
g++ xxx.cpp -fPIC -shared -o libxxx.so
-shared:表示生成共享库
-fPIC:编译为位置独立的代码,在可执行程序加载的时候可以存在放在内存中的任何位置
使用:
可以在文件头部extern 想要用到的静态库函数 编译时加上 -L[库文件路径] -lxxx,但运行时错误:找不到该动态库
解决方法3种:
(1)将库复制到/usr/lib和/lib下,运行 ldconfig命令
(2)在执行命令前加环境变量,LD_LIBRARY_PATH=[动态库文件路径],
然后export LD_LIBRARY_PATH=/home/hn/tmp/dongtaiku:$LD_LIBRARY_PATH
(3)修改/etc/ld.so.conf文件,将动态库文件路径加到该文件中,另写一行就行,
不必加include,加上无效,然后ldconfig,系统就会把这个路径作为默认路径
实例:
a、编写好动态库对应的cpp文件
b、生成动态库文件 g++ out.cpp -fPIC -shared -o libout.so
c、编写调用程序main.cpp
d、生成可执行文件 g++ main.cpp -o mian -L. -lout
e、执行时会报错提示不能加载共享库
使用方法一:亲测可行
使用方法二:亲测可行
使用方法三:亲测可行
程序调用
主程序呼叫另一个子程序
1.各个程序先编译.o文件
2.在将各个.o文件链接成一个可执行文件
编译时加入额外函数库连接的方式:
gcc math.c -lm -L/lib -L/lib64
//包含头文件后,gcc会主动抓取相关的函数库,此处为示例,实际不需要 -L/lib -L/lib64。
//-l(小写的L):加入某个函数库的意思后接库名如下条
//m:指libm.so lib与.a或.so都不用写
//-L后指定搜索目录
//-I(大写的i):指定头文件搜索目录