问题背景
在c/c++大项目中我们会使用到其他部门提供的so动态库,如果两个部门函数命名不规范出现符号冲突的几率非常大。历史原因我们需要在几十万代码中对函数重命名,手工来改肯定是无法接受的,在解决问题过程中发现,clang的分词配合sed命令来修改很好提高了效率。
符号冲突
学习地址: https://www.cnblogs.com/skynet/p/3372855.html
书籍: 程序员的自我修养——链接、装载与库
解决:https://blog.csdn.net/found/article/details/105263450
- 通一个源文件中出现两个相同符号出现编译错误如:
#include <stdio.h>
#include <stdlib.h>
static void test(int a)
{
printf("file:%s func:%s %d\n",__FILE__, __FUNCTION__, a);
}
void test(int a)
{
printf("file:%s func:%s %d\n",__FILE__, __FUNCTION__, a);
}
#include <stdio.h>
#include <stdlib.h>
static void test(int a)
{
printf("file:%s func:%s %d\n",__FILE__, __FUNCTION__, a);
}
static void test(int a)
{
printf("file:%s func:%s %d\n",__FILE__, __FUNCTION__, a);
}
- 内部static 符号和外部提供so导出冲突,内部使用时使用static函数
- 内部导出符号和外部符号冲突,调用时使用内部函数
- 程序连接的so导出符号冲突
1). 程序运行时会加载so动态库对外提供的函数名到全局符号表。如果发现so中函数已经被加载到全局符号表中,后面的函数会被忽略。
//test1.c gcc -shared -fPIC -o libtest1.so test1.c
#include <stdio.h>
#include <stdlib.h>
void test(int a)
{
printf("file:%s func:%s %d\n",__FILE__, __FUNCTION__, a);
}
//test2.c gcc -shared -fPIC -o libtest2.so test2.c
#include <stdio.h>
#include <stdlib.h>
void test(int a)
{
printf("file:%s func:%s %d\n",__FILE__, __FUNCTION__, a);
}
//main.c gcc main.c -o main -L./ -ltest1 -ltest2 -Xlinker --rpath ./
//输出
#include <stdio.h>
#include <stdlib.h>
void test(int a);
void test_a();
void test_b();
void main()
{
test(1);
}
2). 连接库加载是按照广度优先加载的 比如 下面依赖会先加载 liba.so libb.so libc.so 最后加载libd.so
main -->libtest1.so
—> libtest2.so—>lib.so
—> libtest3.so
//gcc -shared -fPIC -o lib.so test3.c
#include <stdio.h>
#include <stdlib.h>
void test()
{