Unix学习(二)

来源:互联网 发布:手机设计家具软件 编辑:程序博客网 时间:2024/05/16 16:15

库的升级:如果是静态库需要把整个库重新生成一遍然后再重新编译可执行文件。动态库,可执行文件会自动使用新库。

在程序中了解自己的运行环境
在控制台只要使用env就可以查看自己的环境
程序员可以使用main的argv获得命令行的参数
编译器的环境gcc,它有很多扩展
预定义宏: FILE源文件的名字
LINE:源码的行号
DATE;日期;TIME:时间
FUNCTION:
C++程序中才会有的__cplusplus用来区分是c还是c++

pragma pack结构的对齐补齐

默认情况使用4字节对齐补齐
支持属性修饰attribute((属性))
函数的修饰constructor/destructor 构造函数/析构函数(要让C++中代码在main之前执行,可以写一个类让他有构造析构函数,然后定义一个全局变量,就可以让它的构造函数先执行)
这两个属性可以用来在main运行之前之后做初始化和清理操作(这个属性修饰完全是编译器的扩展,如果是其他类型的编译器就不行了,所以它的兼容性不好)
结构的扩展aligned(1)/aligned(4)按几字节对齐补齐
typeof(x)编译的时候用来取得一个数据的类型名
比如在定义宏的时候需要定义一个变量来做中间变量:

define swap(x, y) { typeof(x) t = x, x = y; y = t }

Linux环境工具
nm 用来显示目标文件中(.o,.so)的符号(名字)清单
ldconfig 把动态库放到缓存中去,加载的时候能加快速度,系统启动的时候会自动执行
ldd 查看依赖关系,一个程序依赖于哪些动态库。
linux-gate.so.1 => (0xb772f000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7558000)
/lib/ld-linux.so.2 (0x8006b000)
这些带数字结尾的都是相对应的so文件的软链接文件,只是为了标志当前so的版本号
strip 去掉目标里的冗余的信息,一般是一些调试信息
objdump 显示更加详细的目标文件(.o,.out二进制文件)的附加信息

3、动态加载动态库
编译的时候库不存在,只有在运行的时候才会有,比如有些网络程序就需要通过网络加载库。如果有库就运行,没有就不运行。有时候库分中文英文版,需要运行时根据用户选择加载执行不同的库。这就需要加载执行动态库的功能:
dlopen打开一个动态库,加载成功返回一个指针,习惯上称作句柄handle。失败返回一个无效的句柄NULL。标志flag有两个取值一个是RTLD_NOW,另外一个是RTLD_LAZY。(real time load),立即加载和懒加载即什么时候用到什么时候加载。
void *dlopen(const char *filename, int flag);
潜规则:返回指针的函数一般用正常地址表示成功,NULL表示失败。个别例外返回(void*)0xffffffff表示失败。
如果运行失败可以用char *dlerror(void);获得一个字符串描述动态库操作发生了什么错误。
使用void *dlsym(void *handle, const char *symbol);根据名字查找在动态库中的地址。如果名字不存在失败返回NULL。有可能有些动态库的符号真的在0的地方,但是一般不会有这种情况。如果一定要鉴定是否正确先调用dlerror清除上次调用错误,在查找之后再调用dlerror查看是否有错误。这种严格判断能够确保完全正确,大部分情况下不必这么做,直接判空就行了。使用完成之后就需要卸载动态库,int dlclose(void *handle);。
这些方法调用需要加入头文件dlfcn.h
这些函数在动态库libdl.so中,gcc -ldl …来链接这个动态库。

0 0
原创粉丝点击