LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1041|回复: 3

[求助]关于库连接的同名函数问题,迷茫中......[已解决]

[复制链接]
发表于 2009-12-15 10:15:13 | 显示全部楼层 |阅读模式
各位达人

在下最近在工作中碰到一个库连接的同名函数问题,百思不得其解,现将其拿出来请大家帮助我看看究竟是怎么回事。

**求助**
请教各位,谁能跟我解释一下下述现象究竟是为什么?应该如何做才能是输出满足我所期待的结果?

**现象**
1. 编写了以下代码:
    - lib3.c: 定义函数func2(), func4(),其中, func4()直接调用func2().该文件中的func2()会输出信息"Func2() from libdrv3.so"
    - lib2.c: 定义函数func2(), func3(),其中, func3()调用lib3.c中的func4().该文件中的func2()会输出信息"Func2() from libdrv2.so"。
这里的func2只是为了后续测试存在,写代码时没有真实想要调用。另外,这里的func2的接口声明与lib3.c中的func2()相同。
    - lib1.c: 定义函数func1().其中, func1()调用lib2.c中的func3()
    - main.c: 定义函数main(). 其中, main()调用lib1.c中的func1()

另外,上述代码在同一目录下。

2. 编译上述代码,命令分别如下:
$gcc -shared -fPIC lib3.c -o libdrv3.so
$gcc -shared -fPIC -ldrv3 -L./ lib2.c -o libdrv2.so
$gcc -shared -fPIC -ldrv2 -L./ lib1.c -o libdrv1.so
$gcc -ldrv1 -L./ main.c -o test

3. 执行上述程序test
$export LD_LIBRARY_PATH=`pwd`{LD_LIBRARY_PATH}
$./test
    期待结果: 输出"Func2() from libdrv3.so"
    实际结果: 输出"Func2() from libdrv2.so"

这个问题已经困扰我好几天了。不知道为什么错。
我觉得代码写得应该没有问题,我倾向于认为是编译选项存在遗漏考虑。不知道这种想法是否正确。

[解决方法]
参考下述文章:
http://people.redhat.com/drepper/dsohowto.pdf
发表于 2009-12-15 11:09:36 | 显示全部楼层
您的问题就像迷宫,让人迷茫。。。
如果真想让人帮你,show your code(gun)。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-12-15 11:45:35 | 显示全部楼层
不好意思,因为这几个程序只是为了测试临时写的,很简单。
所以没想到要发上来。

现在把它们贴出来了,请大伙儿看看

  1. /* main.c */
  2. #include <stdio.h>

  3. void func1();

  4. int main()
  5. {
  6.         func1();
  7. }
复制代码

  1. /* lib1.c */
  2. #include <stdio.h>

  3. void func3();

  4. void func1()
  5. {
  6.     func3();
  7. }
复制代码

  1. /* lib2.c */
  2. #include <stdio.h>
  3. void func4();

  4. void func2()
  5. {
  6.         printf("\nfunc2 in libdrv2.so.\n");
  7. }

  8. void func3()
  9. {
  10.         func4();
  11. }
复制代码

  1. /* lib3.c */
  2. #include <stdio.h>

  3. void func2()
  4. {
  5.         printf("\nfunc2 in libdrv4.so\n");
  6. }

  7. void func4()
  8. {
  9.         func2();
  10. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-12-17 09:17:35 | 显示全部楼层
各位

关于这个问题,我找到一篇文章。
在这篇文章的指导下,已经顺利解决这个问题。

解决方法的话,就是通过对库中暴露的符号进行控制(有点类似于Windows下的DEF文件)。
这篇文章主要描述的是基于Linux GCC环境下的做法。
我试了一下,至少对于 Solaris CC的环境中,也有类似的方法。
具体方法就不贴了,把那篇文章的地址发出来给大家共享一下吧。

http://people.redhat.com/drepper/dsohowto.pdf

另外,其实为了解决同名函数问题,
使用 dlopen()系列函数来动态绑定也是一个选择。
不过这么做的成本对于一份已经写定的代码而言是比较高的,
毕竟涉及到源码的修改。
除非在一开始做的时候就决定使用 dlopen() 系列函数在运行时动态加载。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表