1

我正在编译一个由多个项目组成的应用程序,这些项目生成动态库(LINUX 上的共享库)。当然,不同的项目正在链接到我编译的其他项目。我在 Ubuntu 下使用 CodeBlocks 10,使用 GCC 编译器。

由于根据用户指定的参数,应加载不同的库,在我的主应用程序中,我正在加载适当的库,根据决定,使用以下行:

dll = dlopen("my_library.so", RTLD_LAZY);

如文档中所述,dlopen 会自动加载库如果库依赖于其他共享库并且该过程以递归方式完成。

问题是,在我的 dlopen 之后,我调用 dlerror() 以了解发生了什么,我收到以下错误:

../../../../gccDebug/os.so:无法打开共享对象文件:没有这样的文件或目录。

只看错误,我就完全理解了,因为它在下面的 2 个文件夹比它应该的要多。问题是为什么?

我的意思是:我使用相对路径在项目上显式加载共享库。在我的主应用程序上,工作目录是 ../../gccDebug。我使用 dlopen 加载 mylibrary.so,它显式加载(在项目选项中)../../gccDebug/gui.so。然后这个 gui.so 也显式加载(在项目选项中)../../gccDebug/so.os

在我看来,正在发生的事情是,他正在附加路径,使其在第 3 次“迭代”中实现,他正在寻找一条已经在搜索太多文件夹的路径。如果第一次递归加载(gui.so)工作得很好,为什么第二次递归加载(so.os)给出了一个奇怪的路径?

使用 dlopen 函数递归加载共享库有什么问题?

4

1 回答 1

2

每个路径都应该与执行加载的库相关,因此要../../gccDebug/gui.so在它应该加载的同一目录中加载某些内容./gui.so

额外../..的是因为你已经告诉了一些../../gccDebug东西在 ../../gccDebug _relative to itself_ which relative to your program's working directory is../../gccDebug/../../gccDebug i.e.../../../gccDebug`

对不同的库执行几次,您将获得..所看到的不需要的组件的数量。

你确定gui.so实际加载了吗?难道是在链接时mylibrary.so复制了../../gccDebug/os.so依赖关系gui.so,所以在运行时试图在加载之前加载它gui.so

你有没有ldd mylibrary.so看过它试图找到什么?您还可以使用readelf -d mylibrary.so来查看库的动态部分的内容。

于 2013-03-07T14:19:40.770 回答