之前写TLPI上的代码一直是手动进行错误处理,感觉代码冗余量很大,最后还是决定使用书上的tlph_hdr.h,顺便回顾下动态库的创建/使用。

参考很久之前的一篇博客 linux上静态库和动态库的编译和使用

但是感觉这篇博客写了后我一直没真正用过动态库,于是花了些时间复习下,结果倒好,一直出问题。

xyz@ubuntu:~/lib$ ls
a.out f.c g.c h.c libutil.so main.c util.h

f.c g.c h.c分别是3个函数f()、g()、h()的定义,util.h是这3个函数的声明,main.c包含了util.h,并在main()函数中调用了这3个函数。

a.out则是成功生成的程序,生成过程如下

xyz@ubuntu:~/lib$ gcc f.c g.c h.c -fpic -shared -o libutil.so
xyz@ubuntu:~/lib$ gcc main.c -L. -lutil

第一步编译了3份包含函数具体实现的源文件,第二步编译了主程序。

其中-L.将当前目录设为动态库查找位置,-lutil代表查找的动态库为libutil.so,这只是语法糖,这句命令用libutil.so替换-lutil也可以。

最后运行a.out时报错

./a.out: symbol lookup error: ./a.out: undefined symbol: f

自己瞎折腾半天不知道原因,起初怀疑动态库生成错误,没有包含3个函数,但是命令并没错。最后还是动用搜索引擎,试着用ldd(1)来查看程序依赖库(ldd的使用在TLPI的第3章 3.3中查找glibc共享库的位置时也使用过)

xyz@ubuntu:~/lib$ ldd a.out
linux-vdso.so. => (0x00007fff509eb000)
libutil.so => /usr/lib/x86_64-linux-gnu/libutil.so (0x00007f1a9e581000)
libc.so. => /lib/x86_64-linux-gnu/libc.so. (0x00007f1a9e1b7000)
/lib64/ld-linux-x86-.so. (0x000055fcfc069000)

原因出来了,系统自带了一个libutil.so,我自定义的动态库和它重名了,由于动态库是优先查找系统路径(再其次是-L后面的路径,在这里是当前目录),系统自带的libutil.so自然不会有f() g() h()这三个函数,因此f()被认为是未定义的符号,即找不到函数f()的具体定义。

只要改个名字就行了,然后就遇到了下面错误

xyz@ubuntu:~/lib$ gcc f.c g.c h.c -fpic -shared -o libfgh.so
xyz@ubuntu:~/lib$ gcc main.c -L. -lfgh
xyz@ubuntu:~/lib$ ./a.out
./a.out: error while loading shared libraries: libfgh.so: cannot open shared object file: No such file or directory

最好的解决方式还是把动态库目录加到环境变量里,而不是把动态库随便扔个系统目录。

xyz@ubuntu:~/lib$ export LD_LIBRARY_PATH=$(pwd)
xyz@ubuntu:~/lib$ echo $LD_LIBRARY_PATH
/home/xyz/lib
xyz@ubuntu:~/lib$ ./a.out
f()
g()
h()

运行成功,然而这个环境变量重启后就没了,所以需要把它添加到在~/.bashrc末尾,此时就需要把当前目录用绝对路径表示了

export LD_LIBRARY_PATH=/home/xyz/lib 

这样系统重启之后便仍可运行a.out,如果需要通知系统.bashrc文件已更新,可用命令source ~/.bashrc

写动态库时遇到了symbol lookup error问题的更多相关文章

  1. Linux:编译动态库时遇到的错误relocation R_X86_64_32 against `a local symbol'

    编译动态库时遇到如下错误: ... ... relocation R_X86_64_32 against `a local symbol' can not be used when making a ...

  2. linux c编程调用系统的动态库时,要使用dlopen等函数吗?

    同问 linux c编程调用系统的动态库时,要使用dlopen等函数吗? 2012-11-27 21:55 提问者: hnwlxyzhl 我来帮他解答 满意回答 2012-12-07 09:08 li ...

  3. vs指定QT的工作目录(依赖第三方动态库时,这时vs编译出来后,运行会提示缺少动态库)good

    当一个工程依赖第三方动态库时,这时vs编译出来后,运行会提示缺少动态库.解决方法: 项目->属性->调试: 工作目录:指定程序运行时的目录 环境:指定程序运行时的环境变量 我们可以在环境变 ...

  4. 由一次 symbol lookup error 引发的思考

    开发一个跨平台的项目的时候,大部分时候都是在VS下进行编码,所以也就使用了VS的解决方案来管理项目. 因为要跨平台,当时网上看scons这个工具不错,所以在linux下就使用了scons来作为编译脚本 ...

  5. ldd "symbol lookup error"问题解决

    http://www.linuxquestions.org/questions/slackware-14/symbol-lookup-error-usr-lib-libgtk-x11-2-0-so-0 ...

  6. symbol lookup error *** , undefined symbol 错误

    在重装samba过程后遇到一些问题,使用 gdb 时产生报错: gdb: symbol lookup error: gdb: undefined symbol: PyUnicodeUCS2_FromE ...

  7. symbol lookup error

    今天编译代码时出现这样的错误提示: “./test: symbol lookup error: ./test: undefined symbol: ……” 问题原因是:test使用的动态库和makef ...

  8. fastDfs V5.02 升级到 V5.08版本后,启动报错:symbol lookup error: /usr/bin/fdfs_trackerd: undefined symbol: g_current_time

    /libfastcommon-1.0.36 # ./make.sh cc -Wall -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -g -O3 -c -o hash.o ...

  9. centos perl: symbol lookup error: /usr/local/lib64/perl5/auto/DBD/mysql/mysql.so: undefined symbol: mysql_init

    之前在安装天兔数据库监控工具lepus的时候,运行时一直报perl: symbol lookup error: /usr/local/lib64/perl5/auto/DBD/mysql/mysql. ...

随机推荐

  1. 安装VMware Tools:Ubuntu

    1.首先准备好linux.iso,在安装目录下应该可以找到,我使用的是这个: 链接:http://pan.baidu.com/s/1nuGQyIt 密码:b5mn 2.打开Ubuntu,CD中加载该i ...

  2. 022——VUE中remove()方法的使用:

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 【网络编程】inet_addr、inet_ntoa、inet_aton、inet_ntop和inet_pton区分

    先上一张图 1.把ip地址转化为用于网络传输的二进制数值 int inet_aton(const char *cp, struct in_addr *inp); inet_aton() 转换网络主机地 ...

  4. python 获取当前时间(关于time()时间问题的重要补充)

    python 获取当前时间   我有的时候写程序要用到当前时间,我就想用python去取当前的时间,虽然不是很难,但是老是忘记,用一次丢一次,为了能够更好的记住,我今天特意写下python 当前时间这 ...

  5. ios入门第一天

    写在两个@ 之间的为oc语言   之外的为c语言  访问权限一旦定义了一个 除非在重新定义一个 否则都是该类型的 如 @protected  int i;  int j;  int l;int n; ...

  6. 对于get方法是否需要synchronized修饰

    具体用法没有总结,只是说明一个用法而已,对于以前个人理解出现的偏差 [问题描述] 对于一个计数功能的实现,获取值的方法是否需要加锁? [以前理解] 我只需要在进行累加的方法上进行加锁即可,这样保证其可 ...

  7. jmeter的三种参数化

    以FTP请求(用户.密码)为例:(其他都相同) 1.文件参数化 使用配置元件中的CSV Data Set Config 配置CSV Data Set Config: 文件中存储ftp登录的用户名和密码 ...

  8. python项目中requirements的巧用(一键导入所有安装包)

    一个Python 项目中可能安装很多安装包, 再次创建虚拟环境是需要重新安装的话很麻烦也费时间, 或者项目部署的时候避免重装, 可以将现有项目的所有安装包记录在requirements.txt 文件, ...

  9. linux下如何启动和关闭weblogic .

    在你定义的域中可以找到如下命令: /[youHome]/domains/[yourDomain]/startWebLogic.sh /[youHome]/domains/[yourDomain]/st ...

  10. jQuery 滑动选项卡jQuery tabslet

    Tabslet   Yet another jQuery plugin for tabs, lightweight, easy to use and with some extra features ...