记录一次采坑--如何处理Linux动态库同名函数?
一、背景介绍
需求描述:业务提供一个鉴权的静态库,我只需要从url 和 参数中提取相应的参数传给业务的静态库,将静态库的处理结果直接返回给业务(return < 0,直接返回403)。 但是最近业务反馈,请求部分url直接返回Error:-1015错误,不符合预期。 二、分析过程业务刚开始反馈问题,我的第一反应:怎么可能是我的问题,我就仅仅写了一个so(暂时命名1.so),直接调用了你们静态库,这个-1015不就是你们库返回的结果。 有问题也是业务提供的库有问题。 或者就是业务配置不正确。
最后还是走到方案3,业务说printf的结果不符合预期,经业务提醒,突然意识到是不是调用链接到其他库的xx_func? 因为项目比较大, 涉及的库比较多,我用nm认真检查了编译时加载的库,竟然还真找到一模一样的接口xx_func nm ./lib/liba.a | grep xx_func 编译代码的时候,赶紧去掉了同名函数库(因为在makefile文件编译的时候某些公共库默认都会编译进去)。重新编译版本。 没有想到,去掉同名函数库,还是存在问题,为什么呢?到底是哪里的问题? 随手直接 到这里问题的原因也算是找到了,下面接着就是如何解决问题? 三、解决方案1. 最简单的方案 -- 修改函数名称因为业务本身提供的静态库,用 2. -fvisibility=hidden -- 最安全最推荐的做法现在C/C++这一块有几十年的历史,该踩的坑大家都应该踩过去了。gcc编译器就直接提供
四、练习实践---验证动态库的同名函数调串1.代码结构很简单. ├── libqqmusic.c ├── libtmemusic.c ├── main ├── main.c ├── makefile └── README.md 2. libqqmusic.c//libqqmusic.c #include<stdio.h> int get_music_id() { return 1111; } void qqmusic_print() { printf("qqmusic id: %dn",get_music_id()); return; } 3. libtmemusic.c//libtmemusic.c #include<stdio.h> int get_music_id() { return 2222; } void tmemusic_print() { printf("tmemusic id: %dn",get_music_id()); return; } 4. main.c//main.c #include<stdio.h> int main(int argc,char *argv[]) { printf("startn"); tmemusic_print(); qqmusic_print(); tmemusic_print(); printf("endn"); return 0; } 5.makefile# 1. create /etc/ld.so.conf.d/vaynedu-test.conf # /usr/lib64/vaynedu # 2. mkdir /usr/lib64/vaynedu # # 3. cp *.so /usr/lib64/vaynedu all: gcc -g -fpic -c -o libqqmusic.o libqqmusic.c gcc -g -shared -o libqqmusic.so libqqmusic.o gcc -g -fpic -c -o libtmemusic.o libtmemusic.c gcc -g -shared -o libtmemusic.so libtmemusic.o cp *.so /usr/lib64/vaynedu @ldconfig #gcc -g -o main main.c -L. -lqqmusic -ltmemusic gcc -g -o main main.c -L. -ltmemusic -lqqmusic @echo -e "nncompile completenn" clean: rm -fr *.so *.o 6.测试结果--证明同名函数库受编译时加载顺序的影响将tmemusic放在前面 将qqmusic放在前面 gcc -g -o main main.c -L. -lqqmusic -ltmemusic 五、总结《程序的自我修养-链接、装载与库》应该好好的啃一遍,这个一个后台开发必备的知识技能
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |