关于linux下连接动态库问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于linux下连接动态库问题相关的知识,希望对你有一定的参考价值。
1.在我当前目录下有libSDL2-2.so.0(动态库)和test.c这两个文件,test.c要连接SDL动态库,编译选项:
gcc test.c ./libSDL2-2.so.0
在编译的时候指定了动态库,但是在执行./a.out时提示:
./a.out: error while loading shared libraries: libSDL2-2.0.so.0: cannot open shared object file: No such file or directory
ldd a.out输出:
linux-gate.so.1 => (0xb777c000)
libSDL2-2.0.so.0 => not found
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75a9000)
/lib/ld-linux.so.2 (0xb777d000)
即SDL这个库没有找到,但是我在编译test.c的时候已经指定了SDL动态库,不应该会找不到啊
2.为了验证上个问题,自己又编了个动态库
function.c:
#include <stdio.h>
void function(void)
printf("hello world\n");
my.c:
void function(void);
int main(void)
function();
return 0;
<1>首先编译function.c为动态库:gcc -shared -fPIC function.c -o function.so
生成function.so动态库
<2>编译my.c: gcc my.c ./function.so
生成a.out
ldd a.out
linux-gate.so.1 => (0xb77a4000)
./function.so (0xb779e000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75ce000)
/lib/ld-linux.so.2 (0xb77a5000)
发现function.so是有地址的
执行./a.out能够正确打印出hello world
3.为什么第一个连接SDL库的时候不行??而连接function.so的时候却行?二个的操作步骤都一样啊?
还请高手解答下,谢谢!!
1.gcc test.c ./libSDL2-2.so
2.gcc test.c -lSDL2-2
3.gcc test.c -L/home/test -lSDL2-2
一般的编译参数都是按照2或3去写
2写法的含义是从/lib或者/usr/lib目录下寻找名称为SDL2-2的库,即寻找/lib/libSDL2-2.so或者/usr/lib/libSDL2-2.so文件进行链接,当然如果没有动态库就会去找静态库,再没有应该就会在编译时报错
3写法的含义是从-L参数首先从指定的目录中寻找需要链接的库文件,随后再去寻找系统文件夹中是否存在需要的库
1写法的含义是将当前目录下的./libSDL2-2.so.0文件链接进最终文件,因此执行readelf -a a.out后在动态库部分所看到的路径就是./libSDL2-2.so.0,进而在执行文件时仅会从当前目录下寻找libSDL2-2.so.0文件,当执行文件时所在的目录下没有该文件时就会出现找不到库文件的操作
你第二次操作时,因为function.so库文件与a.out文件在同一个目录,同时也是在该目录下执行的ldd操作及运行a.out,a.out在加载动态库时从当前目录下找到了所需要的库文件,此时能够执行成功(ldd命令实质是一个脚本,通过设置环境变量运行动态库链接器来输出所有待链接的动态库)。
你可以试试将a.out拷贝至其他目录再次运行,将出现和第一次操作时一样的现象,找不到function.so文件。
具体的解决方法就是修改编译参数,将./libSDL2-2.so.0修改为-lSDL2-2并将libSDL2-2.so.0文件拷贝至/usr/lib目录下,并且可能因为没有修改链接器的缓存文件(将可能找不到带版本号后缀的动态库),需要在/usr/lib目录下建立一个文件连接(ln -s libSDL2-2.so.0 libSDL2-2.so)或者直接修改名称为libSDL2-2.so追问
首先非常感谢你的回答,另外对你的回答有点疑问:
你所述的
“1写法的含义是将当前目录下的./libSDL2-2.so.0文件链接进最终文件......."
--------我在问题的开始已经说明了libSDL2-2.so.0文件是在当前目录下,并且可执行文件也在同一个目录。
这个方法我知道,关于动态库路径有4种方法,我只是想知道为什么上面第二个例子可以,第一个却不可以?
linux 下如何将动态链接库.so进行反编译后,换编译器重新编译?
我遇到一个问题,我们在arm板上跑一个程序,结果它要依赖的动态库是用低版本的gcc编译器编译的, 假如都用低版本的编译器,另一个程序又编译不过!
所以我想能不能把动态库反汇编后,用高版本编译器重新编译呢?
以上是关于关于linux下连接动态库问题的主要内容,如果未能解决你的问题,请参考以下文章