Linux下静态库和共享库中的同名函数

amagic 2011-08-19 10:07:28
最近遇到一个静态库和共享库中函数冲突的问题,还请大家帮忙看一下:

为了说清楚,我举一个简化了的 例子:
一个程序,含有两个模块,ModuleA和ModuleB,其中ModuleA用到了共享库libA.so,而ModuleB用到静态库libB.a。其中libA.so和libB.a都是第三方的库,没有源码。

我需要在ModuleB中调用libB.a提供的函数helloWorld(),但libA.so中也提供了一个同名函数helloWorld()。像这样的同名函数还有很多。

问题是,在程序运行的时候,我发现ModuleB所调用的helloWorld()不是libB.a的,而是libA.so的。


请问有没有办法使ModuleB只调用libB.a中的某个函数,即使这个函数在其他库中也有定义。
...全文
492 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
liuysheng 2011-12-09
  • 打赏
  • 举报
回复
17楼的,比较详细,,给力,,
hacqing 2011-08-19
  • 打赏
  • 举报
回复
http://blog.csdn.net/crazyjixiang/article/details/6614250
Abel Lee 2011-08-19
  • 打赏
  • 举报
回复
不知道为什么会造成这种情况?
我以前做过非标准函数接口隐藏,你去查GCC选项,可以屏蔽某些库中的接口!
赵4老师 2011-08-19
  • 打赏
  • 举报
回复
直接修改.so或.a中导出函数的名字不就行了?
jernymy 2011-08-19
  • 打赏
  • 举报
回复
编译选项中的
LDFLAGS += --static
amagic 2011-08-19
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 xunxun1982 的回复:]

第一种方法:使用libB进行静态链接,libA等用到的时候再去dlopen他

第二种方法:自己编写个libB.c,里面写函数helloWorld2(),里面直接调用helloWorld()
编译链接时采用gcc -shared libB.c -o libB.so libB.a
那么这个函数的名称就变成你自定义得了,然后再和libA.so一起用
[/Quote]

第一种方法可行,但不适合我。
讨论一下第二种方法。ModuleB本身就是一个动态库,会被程序在运行时加载。所以你这里的libB.so跟直接ModuleB没有区别,我觉得应该无法保证正确的helloWorld()被调用。
一叶之舟 2011-08-19
  • 打赏
  • 举报
回复
我看过一片文章,说好像静态库也可以像动态库一样加载使用,没有试验过,
amagic 2011-08-19
  • 打赏
  • 举报
回复
回复#9 dahuaixiaohuai:

谢谢回复,我理解你的意思。但你说的方法是要改变ModuleA,因为只有它才会使用libA.so,对我来说这不可行,因为ModuleA是很多个模块,我不清楚里面的实现,也不清楚它使用了libA.so的哪些函数。
xunxun 2011-08-19
  • 打赏
  • 举报
回复
第一种方法:使用libB进行静态链接,libA等用到的时候再去dlopen他

第二种方法:自己编写个libB.c,里面写函数helloWorld2(),里面直接调用helloWorld()
编译链接时采用gcc -shared libB.c -o libB.so libB.a
那么这个函数的名称就变成你自定义得了,然后再和libA.so一起用
一叶之舟 2011-08-19
  • 打赏
  • 举报
回复
静态库只能链接,所以你没有办法选择函数的使用方法,但动态库除了链接外,可以动态加载,在加载的模块中,你如何使用这个函数,如把调用的函数指针如何名,决定权你手里。这样就可区分两个函数。
如果同名函数过多,做一个中间层.so,如moduleaaaa.so,在里面把libA.so中的函数通过函数指针的方式重命名,通过调用moduleaaaa.so的接口,去调用里面的函数指针,达到调用libA.so中函数的效果,不知能否明白。
amagic 2011-08-19
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 xunxun1982 的回复:]

引用 4 楼 dahuaixiaohuai 的回复:

使用动态加载的方法加载libA.so,获取其函数地址,函数指针命名为funso,
使用静态连接的方式链接静态库libB.a,直接使用其原函数名,这样就把两个函数区分开了。

我也认为这个方法较为可取
还有一个方法是
使用ar把libB.a解包
然后把那个函数的.o删除
然后重新打包
不过有可能造成其他函数缺失
[/Quote]

见上一个回复。
由于libB.a是静态库,不能用dlopen()的方法来使用其中包含的库。不知道有没有方法对静态库采用类似的操作?
amagic 2011-08-19
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 dahuaixiaohuai 的回复:]

使用动态加载的方法加载libA.so,获取其函数地址,函数指针命名为funso,
使用静态连接的方式链接静态库libB.a,直接使用其原函数名,这样就把两个函数区分开了。
[/Quote]

希望不改动ModuleA,因为这个libA.so被很多个模块(泛指ModuleA)调用,这里的例子做了简化。我只能修改ModuleB。
amagic 2011-08-19
  • 打赏
  • 举报
回复
不是编译引起的,ModuleA和ModuleB都是独立编译的,ModuleB link的确实是libB.a。

xunxun 2011-08-19
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 dahuaixiaohuai 的回复:]

使用动态加载的方法加载libA.so,获取其函数地址,函数指针命名为funso,
使用静态连接的方式链接静态库libB.a,直接使用其原函数名,这样就把两个函数区分开了。
[/Quote]
我也认为这个方法较为可取
还有一个方法是
使用ar把libB.a解包
然后把那个函数的.o删除
然后重新打包
不过有可能造成其他函数缺失
一叶之舟 2011-08-19
  • 打赏
  • 举报
回复
使用动态加载的方法加载libA.so,获取其函数地址,函数指针命名为funso,
使用静态连接的方式链接静态库libB.a,直接使用其原函数名,这样就把两个函数区分开了。
luciferisnotsatan 2011-08-19
  • 打赏
  • 举报
回复
那两库各自都没有 namespace?不行可以考虑自己封装下
  • 打赏
  • 举报
回复
加一个中间层,改其中一个模块的名字
nickowen 2011-08-19
  • 打赏
  • 举报
回复
把libB.a放一个自己的库文件路径.
编译B的时候指向该路径及可
自由建客 2011-08-19
  • 打赏
  • 举报
回复
十六楼及以上都是什么跟什么啊!就十七楼靠谱!注意连接顺序即可,就像 $PATH 能划分命令优先级。

64,643

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧