动态库的动态加载
a.out中的指令和数据加载到内存条中,cpu从内存条中把指令和数据读取,cpu执行
如若a.out执行10分钟,其中库只用到1分钟,则另外9分钟库在内存占据空间又不被使用到,造成资源浪费
理想情况:a.out执行中,需要用到库时,库再加载到内存中,用完后将库从内存中卸载
即为动态加载
1.
功能:该场景中,句柄即为指针(windows下句柄不是指针),根据函数的返回值(句柄)寻找加载到内存中的库
如FILE* fp = fopen(),打开文件后,根据文件指针表示文件描述
同理,库加载到内存后,根据句柄表示库
参数:uc中大部分char*类型形参传递的都是字符串,字符串的内容为库名
flag取值已定义好,为两个特殊的宏
例:void* dlopen("libmath",RTLD_LAZY);
2.
符号:库中不一定只有函数,可能也有变量,类
通过句柄访问库
例:void* dlsym(handle,"add")
3.
4.
用fprintf将字符串往stderr(文件)写,相当于往显示器上写
linux中标准输入,标准输出,标准错误是3个特殊的文件
标准输入stdin:键盘
标准输出stdout:显示器
标准错误stderr:显示器
printf是通过标准输出去输出的,通过printf输出字符串到显示器,中间需要经过标准输出缓冲区,缓冲区中1.有\n 或者2.满了 或者3.程序结束了,输出的内容才会从缓冲区显示到屏幕
标准错误没有缓冲区,通过标准错误输出内容一定能显示到屏幕,用fprintf将strerr看作文件
fprintf(stdout,"")等价于printf
*add代表是个指针,(*add)()代表是函数指针,参数是int,返回值是int的函数指针,指针变量名为add
需要链接ldl库
对于运行1年的程序,动态库的动态加载就能体现优势,不然库在内存中占1年
库名写错时,成功跳出错误原因
T:自己定义的
U:调用的
libdl.so:编译时-ldl链接的
libc.so:标准C库
错误处理
错误原因 每个错误对应一个编号 错误号/错误码
文件不存在 1
没有子进程 2
。。。 。。。
int errno = 1/2/。。。
成功输出错误编号
成功输出错误原因
先调malloc再调fopen
malloc出错errno存了个错值,此时用errno判断fopen是否出错不严谨
正确的判断方式是用返回值判断,fopen出错返回值为NULL
man1查命令,如man 1 ls
man2查系统调用接口函数,如man 2 open
man3查标准库,如man 3 printf
linux中有类型size_t,本质为int,很多中间过渡类型会以__做开头
typedef int __size_t
typedef __size_t size_t
main.c编译生成a.out过程中有链接过程,链接过程会生成一些中间过渡的函数
如_init()
看到_反应为过渡角色