库文件:预先编译好的方法的集合
静态库:libxx.a
共享库:libxx.so
printf() -> 实现在 c库 libc.so
库放在 /usr/lib…
头文件放在/usr/include
静态库的生成
先定义 add.c (加法函数) max.c(最大值函数)在main.c中调用这两个函数
尝试生成可执行文件并输出运行结果
发生错误 未在main中声明 add 和 max函数
生成一个头文件来存放两个函数的声明 或者直接在main.c中声明也可以
再次尝试生成可执行文件并输出运行结果
出现错误,提示函数方法未定义,由于头文件test.h中只有函数声明并不包含函数实现.如果用系统实现的库函数系统会默认链接。 而自己实现的函数编译器不清楚位置,所以
引入静态库
先打包.o文件 生成库文件
使用 ar 命令将第一步编译的所有”.o”文件生成静态库,其中:
◼ c 是创建库
◼ r 是将方法添加到库中
◼ v 显示过程
生成可执行文件并输出运行结果
格式:gcc -o main main.c -L 路径 -l库名称
◼ -L 指定库的存储路径(. 代表当前路径)
◼ -l 指定库的名称(不需要前面的‘lib’和扩展名‘.a’)
如果用系统实现的库函数系统会默认链接,而自己实现的函数编译器不清楚位置,所以要用-L指定库的位置
将头文件和生成的库文件移动到标准目录不用指定库文件的位置
静态库在链接这一步就包含在了可执行程序中了,成为了执行程序的一部分。所以删除了之前生成的库程序依然可以正常执行。
使用一些不是c库的库函数时(也就是没有在标准的c库中),使用时也要指定库的名称 比如sqrt() 是在math库中
通过查命令手册
所以在生成可执行程序(程序中使用了math.h中的函数)时 要加上 -lm
共享库的生成
用到的文件
生成共享库
第一步:先将需要生成库文件的所有“.c“文件编译成“.o”文件
第二步:使用 gcc 命令将第一步编译的所有”.o”文件生成共享库
生成可执行程序并执行
gcc -o main main1.c -L. -ltest1
在静态库main中是因为已经把库文件包含到了程序中所以不用找。
生成之后,直接执行 main 程序,发现出错,原因是系统加载共享库时,找不到对应的
共享库文件”libfoo.so”, 但是该库确实在当前目录下存在。这是为什么呢?因为系统默认
只会去存储库的标准位置(/lib 或/usr/lib 等)加载,而不会在当前位置寻找。所以将库拷贝到
/usr/lib 下,再执行程序,就可以成功。
在静态库main中是因为已经把库文件包含到了程序中所以不用找。
如果库不在标准位置下,也可以通过设置环境变量”LD_LIBRARY_PATH”来指定加载库的路径。
先指定环境变量在当前位置(.)
echo $XX 输出变量的值
由于此时的变量只是一个普通的变量不是环境变量也是找不到库文件的。
所以需要把本地的变量转换为环境变量,程序就可以正常运行输出结果
查看使用过的共享库
ldd main
libc.so.6 就是标准C库 libtest1.so就是自己生成的库
删除共享库 程序不能正常执行
静态库和共享库的区别
静态库在链接时将用到的方法包含到最终生成的可执行程序中,而共享库不包含,只做标记,在运行程序时,才动态加载。
main函数中的参数
argc 参数个数 argv 参数内容 envp 环境变量
argv 介绍
argv[0]指向程序运行的全路径名
argv[1]指向在DOS命令行中执行程序名后的第一个字符串
argv[2]指向执行程序名后的第二个字符串
argv[3]指向执行程序名后的第三个字
argv[argc]为NULL
打印参数内容
加上几个参数
打印环境变量