首先要理解
当程序运行时,该运行function这个函数,那么要进行跳转(1.绝对地址2.相对地址)
1.绝对地址:固定的地址,函数地址是0x1000,那么就跳到0x1000
2.相对地址:当前位置,到function函数定义差多少条指令,那么就从当前地址减去x条指令就能跳到function那。
动态库=共享库
静态库创建
ar rcs libmylib.a file.o // rcs 创建一个索引,ar 创建命令
nm libmylib.a//查看静态库里头内容。。
一般库名lib开头
动态库
先把.c变为.o
gcc -fPIC -c a.c //-fPIC 凡是用到地址的地方用相对地址(生成与位置无关的代码 ) -c 只编译不连接(生成.o文件)
gcc -shared -Wl -o libmyab.so a.o b.o
更高级的
gcc -shared -Wl,-soname,libmyab.so.1 -o libmyab.so.1.0.1 a.o b.o
libmyab.so.1 ==> soname
libmyab.so.1.0.1 ===> realname
linkname ===> ln -s libmyab.so.1.0.1 libmyab.so
生成出来只有libmyab.so.1.0.1 第1个1代表版本号
1.修改/etc/ld.so.conf //修改为了其他程序能够调用它
当然你gcc main.c libmyad.so.1.0.1 -o app 编译是完全没有问题的但运行不了诶(库打不开呢 没找到呀~)
ldd app 可以查看运行了那些库哦
2.添加库所在的目录
3.sudo ldconfig -v 更新一下~就好了
此时查看libmyab.so.1 ,,,libmyab.so.1.0.1 这两都有了
lld 是不检测静态库滴
linux 动态库 libmym.so //.so共享库 可在 /lib下查看有很多共享库
windows 动态库 mym.dll
动态库要求代码必须与位置无关,这样库在哪个地方都会执行。
ldd
link name | so name| real name…
so name 只记住库的主版本号 (ldd也只是显示libmycalc.1 主版本号)判断程序在当前电脑能否运行 工作在运行阶段
link name 方便编译,链接使用而已 makefile 里用它
主版本号改变=>函数接口可能改变了
次版本号改变(1.10 1.11)=> 某些地方小改动,不影响使用过1.10的程序(例如:函数内部的while循环改成for循环等等。。)
link name -> real name
so name -> real name
刚才的app只记录大版本号 1 而小版本号 1.10中的10 不重要,如果某台电脑版本号是1.20那app也是可以在上面跑的
link name 是考虑makefile使用方便不用修改,编译链接阶段使用