[Linux高级编程]工具&库
来源:互联网 发布:mysql 默认 编辑:程序博客网 时间:2024/04/26 12:56
1 gcc基本命令
-o 输出文件名
-O -O0 -O1 -O2 -O3 编译优化
-g -g0 -g1 -g2 -g3 产生调试信息
-W all error
-Wall 显示所有警告
-Werror 把警告当错误
-w 关闭警告
-c 只编译不连接
-E 预编译
-S 汇编
-D 在命令行定义宏。
#include<stdio.h>int main(){ printf("NUM = %d\n",NUM); return 0;}
-x 指定编译的语言类型 c++ /c /.S /none 自动判定
-std=C89 /C99
编译过程:-E -c -S 自动调用连接器 ,连接器 ld
补充文件名后缀:.a 静态库 .so 动态库 .i 预编译文件
2 静态库的编译与使用
2.1 静态库
函数等代码封装的二进制已经编译的归档文件
采用库的方式管理代码优点:1 容易组织代码 2 复用 3保护代码版权
静态库的静态的含义: 编译好的程序运行的时候不依赖库。库作为程序的一部分编译连接。 静态库本质:就是目标文件集合(归档)
2.2 静态库的编译及使用
编译成目标文件 gcc -c -static 代码文件.c( -static 可选)
cc -c inputInt.c graphic.c
归档成静态库 ar -r 静态库文件 被归档的文件 ar相关参数ar -r libdemo1.a inputInt.o graphic.o//提示完成ar: creating libdemo1.a
察看函数符号表 nm 静态库或者动态库或者目标文件或者执行文件 nm libdemo1.a//显示函数表 inputInt.o:00000000 T inputInt U __isoc99_scanf U printfgraphic.o:00000000 T graphic U putchar
使用静态库 gcc 代码 静态库 cc main.c -ldemo1 -L.
注意:
库命名规则: (1) lib库名.a (2)lib库名.a.主版本号.副版本号.批号
库使用规则: -l 库名 -L 库所在目录
3 动态库的编译与使用
3.1 动态库(共享库)
动态库是可以执行,静态库不能执行 ,但动态库没有main,不能独立执行。 动态库不会连接成程序的一部分。 程序执行的时候,必须需要动态库文件。
ldd 察看程序需要调用的动态库 (ldd 只能察看可执行文件).
readelf -h 察看执行程序头.
3.2 动态库的编译及使用
编译 gcc -c -fpic(可选) 源码文件
gcc -c graphic.c inputInt.c -std=c99
连接 gcc -shared -o动态库文件名 目标文件名
gcc -shared -olibdemo2.so graphic.o inputInt.o
也可一步完成
gcc -fpic -shared graphic.c inputInt.c -olibtiger.so
使用动态库gcc 代码 动态库文件名
gcc 代码 -l库名 -L动态库所在路径
cc -omain main.c -ldemo2 -L.
但是程序运行会提示以下错误:
main: error while loading shared libraries: libdemo2.so: cannot open shared object file: No such file or directory
这是因为程序运行时没有找到动态链接库造成的。
关于动态库的加载:1.找到动态库 2.加载动态库到内存 3.映射到用户的内存空间
系统对动态库查找规则: /lib /usr/lib 到环境变量LD_LIBRARY_PATH指定的路径中查找
缓冲机制: 把/lib:/usr/lib:LD_LIBRARY_PATH加载到缓冲。
/sbin/ldconfig -v 刷新缓冲中so的搜索数据
使用以下方法可以解决此问题
a. 在linux下最方便的解决方案是拷贝libtiger.so到绝对目录 /lib 下(但是,要是超级用户才可以,因此要使用sudo哦,亲)。就可以生成可执行程序了
b.第二种方法是:将动态链接库的目录放到程序搜索路径中,可以将库的路径加到环境变量LD_LIBRARY_PATH中实现:
export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
4 libdl.so 动态加载
上面的方法是在编译时链接,运行时加载的库方法。使用dl接口显式地加载,不需要链接编译。动态库中函数的查找已经封装成库libdl.so
源代码中包含<dlfcn.h> 编译时加入库-ldl 具体方法:
加载
void *dlopen(const char *filename, int flag);
参数:filename, 如果不是绝对路径,那么会从如下路径查找,$LD_LIBRARY_PATH, /etc/ld.so.cache, /usr/lib, /lib.
flag,
使用
void *dlsym(void *handle, char *symbol);
dlsym在加载的对象(由handle所指的共享对象)中搜索在symbol中命名的符号或函数。
dlsym返回指向符号的指针,有错则返回NULL
*检查错误
contst char *dlerror(void);
*卸载共享对象
int dlclose(void *handle);
dlclose卸载handle所指的共享对象。同时使得handle无效。
由于dl库维护着动态库的链接数,只有在dlclose对一个动态库的调用次数等于dlopen时,他们占用的资源才释放。
注意:编译时候要加入 -ldl (指定dl库)
#include<dlfcn.h>#include<stdio.h>#include<stdlib.h>int main(){ void *f1 = dlopen("./libdemo2.so",RTLD_LAZY); if(!f1) {printf("动态库打开失败!\n");return 0; } void (*f2)(int) = dlsym(f1,"graphic"); if(!f2) {printf("函数加载失败:%s\n",dlerror());return(EXIT_FAILURE); } f2(5); dlclose(f1); return 0;}
- [Linux高级编程]工具&库
- linux高级编程
- linux高级编程 函数
- linux 高级编程
- linux 高级编程
- Linux 高级编程
- Linux 高级Socket编程
- Linux 高级Socket编程
- Linux 高级Socket编程
- linux 高级编程
- Linux 高级编程
- Linux 高级编程
- Linux 高级编程
- Linux 高级编程
- Linux 高级编程
- linux高级编程
- Linux 高级编程
- Linux环境高级编程
- 内部排序之堆排序
- 骑士飞行棋游戏
- new和malloc的区别
- DLL调用
- 解决doxygen绘制函数调用失败问题
- [Linux高级编程]工具&库
- c语言NULL和0区别及NULL详解
- 现有服务器oracle数据库调优
- 一步步学习微软InfoPath2010和SP2010--第一章节--介绍InfoPath2010(9)--导出模板
- 让PHP跑在Mac OS X中
- HDU 4315 Climbing the Hill(尼姆博弈变形)
- OpenERP 相同产品相同货位write方法重载优化
- PHP开发者常犯的11个MySQL错误
- JAVA的String、StringBuffer和StringBuilder的区别