当前位置: 技术问答>linux和unix
GCC中静态连接和动态连接的区别(LINUX下)
来源: 互联网 发布时间:2016-08-13
本文导语: 最近正在学习库的用法,写了最基础的libmystring.a的库(里面只有一个add函数),然后编写test程序测试add函数,用ar命令创建好libmystring.a库后,用以下命令编译静态连接的a.out gcc –static test.c –L ./ –lmystring –o a...
最近正在学习库的用法,写了最基础的libmystring.a的库(里面只有一个add函数),然后编写test程序测试add函数,用ar命令创建好libmystring.a库后,用以下命令编译静态连接的a.out
gcc –static test.c –L ./ –lmystring –o a.out
得到静态连接的a.out,./a.out后得到想要的结果;
然后 rm a.out
gcc test.c –L ./ –lmystring –o a.out
得到动态连接的a.out,./a.out后得到想要的结果;
最后把libmystring.a删掉,再./a.out 想象中是不是应该报“找不到XX库的错误”什么之类的,但结果却还是正确的运行输出相应的结果。。。。这是为什么呢? 不是说动态连接的文件在运行的时候需要依赖库文件吗? 是我哪里理解错了呢?
高手指教下!
如下是测试例子:(已经删除了.a库文件,运行a.out后还是输出正确的结果)
add=9
gcc –static test.c –L ./ –lmystring –o a.out
得到静态连接的a.out,./a.out后得到想要的结果;
然后 rm a.out
gcc test.c –L ./ –lmystring –o a.out
得到动态连接的a.out,./a.out后得到想要的结果;
最后把libmystring.a删掉,再./a.out 想象中是不是应该报“找不到XX库的错误”什么之类的,但结果却还是正确的运行输出相应的结果。。。。这是为什么呢? 不是说动态连接的文件在运行的时候需要依赖库文件吗? 是我哪里理解错了呢?
高手指教下!
如下是测试例子:(已经删除了.a库文件,运行a.out后还是输出正确的结果)
gfs@ubuntu:~/study/lib$ ls
a.out mystring.c mystring.h mystring.o test.c
gfs@ubuntu:~/study/lib$ file a.out
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
gfs@ubuntu:~/study/lib$ ./a.out
add=9
|
因为你给他的本来就是一个静态库。
静态库有静态库的用法,静态库是直接打包编译的。
你可以去看看如何使用动态库。
这里,他发现你给他的是一个静态库,他会把他打包编译到可执行文件中,
以后的运行都不依赖你给他的库文件了
静态库有静态库的用法,静态库是直接打包编译的。
你可以去看看如何使用动态库。
这里,他发现你给他的是一个静态库,他会把他打包编译到可执行文件中,
以后的运行都不依赖你给他的库文件了
|
LZ,你需要去看看库文件的原理,以及运作方式。
其实你加不加
-static,结果都是一样的。按照库文件的工作原理,他会先去搜索动态库文件,也即是.so结尾的库文件,
当他找不到动态的(.so文件)的时候,他就会去找静态的库文件,也就是.a结尾的文件。
你这个地方,没什么问题
其实就是库文件找不到动态库了,他就去找静态库,一旦找到,他就工作了
其实你加不加
-static,结果都是一样的。按照库文件的工作原理,他会先去搜索动态库文件,也即是.so结尾的库文件,
当他找不到动态的(.so文件)的时候,他就会去找静态的库文件,也就是.a结尾的文件。
你这个地方,没什么问题
其实就是库文件找不到动态库了,他就去找静态库,一旦找到,他就工作了
|
ar生成的libmysring.a是静态库.
gcc -shared -o libmstring.so mystring.o
生成的才是动态库。
gcc test.c –L ./ –lmystring –o a.out
会优先链接动态库,如果没有就用静态库。
gcc -shared -o libmstring.so mystring.o
生成的才是动态库。
gcc test.c –L ./ –lmystring –o a.out
会优先链接动态库,如果没有就用静态库。
|
你给他一个静态库,他就会用静态方式去连接,编译打包。
他不会把你的静态库转换成动态库的。
这个是原则。
|
LZ,这样给你说:你给他吃什么,他就吃什么。
动态连接来说,他是通吃的。只要你不是在程序中用代码使用动态库。
像你调用函数这种,不加static,他都可以吃的。
但是惟独动态的.so的时候,-static他吃不了。因为你的static已经限定了,你只能给我吃静态的 ,动态的他就不能吃。
如此。。以用-static的时候,给他喂一个.so的,他当然要拒绝了
|
很多库同时带静态(.a)和动态(.so)文件,而且放在同一个目录下,这个时候就需要-static指定用静态库,否则永远会优先使用动态库。
|
-static...
就是让你静态打包编译啊,很多情况下,你会发现,一个库文件,他既有动态库,也有静态库。
为了不依赖平台,我-static,当然就不会去使用.so了,不管你有没有动态库,方正我就只需要你的静态库就ok
你可以在/lib下看看,很多库,都是动态静态都有的。