C ++ linux:dlopen找不到.so库

时间:2013-07-18 06:09:00

标签: c++ linux codeblocks dynamic-library

Reworded Question(尽管已经解决了):

我在使用dlopen(3)在linux上加载共享对象库时遇到了麻烦。该库是由我构建的库系统的一部分,它们都在运行时由中央可执行文件加载。所有这些都被组织到Code :: Blocks中的单个工作区中,其中每个项目在名为Source的目录中被赋予其自己的文件夹,该目录将随程序一起提供。可执行文件的构建目录是从其自己的源代码向后的两个目录,因此exectuable和Source文件夹位于同一目录中。这些库也构建到与可执行文件相同的目录中,因此我自然会传递库的名称我正试图打开如下所示:

int main(int argc, char** argv) {
    void* hLibrary = dlopen("libLibrary.so", RTLD_NOW | RTLD_GLOBAL);
    if(hLibrary == NULL) {
        fprintf(stderr, "%s\n", dlerror());
        return 1;
    }

    return 0;
}

当构建目录与源代码相同时,这一点正在工作,直到我将源代码的目录更改为上述安排。此时的问题是dlerror()返回“无法打开libLibrary.so:没有这样的文件或目录”,即使该文件明显存在并且与可执行文件位于同一目录中。然后我尝试传入“/libLibrary.so”,因为根据dlopen(3)上的手册页,添加/表示相对目录。这返回了同样的错误。

对此的解决方案是需要“./” - 其中“。”表示可执行文件的工作目录 - 并且需要在Code :: Blocks中将工作目录更改为要构建可执行文件的位置。以下工作完美:

void* hLibrary = dlopen("./libLibrary.so", RTLD_NOW | RTLD_GLOBAL);

这并没有真正显示完整的解决方案,但以下内容基本上与我正在做的相同:

void* hLibrary = dlopen("./../../libLibrary.so", RTLD_NOW | RTLD_GLOBAL);

希望这能更好地解释情况。

2 个答案:

答案 0 :(得分:11)

阅读dlopen(3)手册页(例如,在您计算机的终端中输入man dlopen):

  

如果filename包含斜杠(“/”),那么它          被解释为(相对或绝对)路径名。否则,          动态链接器按如下方式搜索库(请参阅ld.so(8)for          更多细节):

   o   (ELF only) If the executable file for the calling program
       contains a DT_RPATH tag, and does not contain a DT_RUNPATH tag,
       then the directories listed in the DT_RPATH tag are searched.

   o   If, at the time that the program was started, the environment
       variable LD_LIBRARY_PATH was defined to contain a colon-separated
       list of directories, then these are searched.  (As a security
       measure this variable is ignored for set-user-ID and set-group-ID
       programs.)

   o   (ELF only) If the executable file for the calling program
       contains a DT_RUNPATH tag, then the directories listed in that
       tag are searched.

   o   The cache file /etc/ld.so.cache (maintained by ldconfig(8)) is
       checked to see whether it contains an entry for filename.

   o   The directories /lib and /usr/lib are searched (in that order).

因此,您需要致电dlopen("./libLibraryName.so", RTLD_NOW) - 而不只是dlopen("libLibraryName.so", RTLD_NOW),希望您的插件位于$LD_LIBRARY_PATH/usr/lib/中......或者添加{ {1}} .(由于安全原因,我不建议这样做。)

作为Jhonnash answered,当LD_LIBRARY_PATH(或dlerror)失败时,您应该使用并显示dlopen的结果:

dlsym

您可能希望阅读一些类似Advanced Linux Programming的书籍,以获得有关Linux系统编程的一般知识。

答案 1 :(得分:2)

关于dlopen已定义;动态库dlopen错误可以是此checked. error未定义的符号link