【问题标题】:dlopen failed: cannot open shared object file: No such file or directorydlopen 失败:无法打开共享对象文件:没有这样的文件或目录
【发布时间】:2012-10-12 01:57:06
【问题描述】:

问题是我使用dlopen加载了一个库(.so是我写的,不是系统库),但是我得到了标题所示的错误。

  1. 我已经收录了dlfcn.h
  2. 在编译器中,我使用了-ldl 命令
  3. 我要加载的只是源代码文件夹,我尝试添加-L.,但没有成功。

【问题讨论】:

    标签: linux


    【解决方案1】:

    如果您要 dlopen 的库不在标准搜索路径中,您有多种选择:

    1. 在 dlopen 中指定文件的完整路径

      dlopen("/full/path/to/libfile.so");

    2. 通过 LD_LIBRARY_PATH 添加库的路径

      LD_LIBRARY_PATH=/path/to/library/ ./executable

    3. 使用 ld -rpath 选项将库路径添加到应用程序。

      g++ -link stuff- -Wl,-rpath=/path/to/library/

    请注意,选项 1 和 3 将库路径硬编码到您的应用程序中。 -rpath 确实有一个选项来指定相对路径,即

    -Wl,-rpath=$ORIGIN/../lib/
    

    将相对路径嵌入到应用程序中。

    【讨论】:

    • 不行,我看文件类型:ELF 32-bit LSB shared object,ARM也是,但是可执行文件是ELF 32-bit LSB可执行,Intel 80386,是平台问题吗?
    • 可执行文件和库都必须为同一个平台编译,是的。
    【解决方案2】:

    找出代码出错的最残酷和有效的方法是以下命令,它将激活共享库的调试模式,并记录在here

    export LD_DEBUG=libs
    

    然后,您会惊讶于弹出这么多信息。不用担心,这些信息会告诉您刚刚键入的命令需要哪些共享库以及在哪里可以找到这些所需的库。例如,如果您键入reset,屏幕将被重置,然后将打印有关共享库reset 命令需要的信息。

    然后,执行“有问题的”可执行文件,看看出了什么问题。


    PS.1:根据您接受的神话解决方案:

    在 dlopen 中指定文件的完整路径

    dlopen("/full/path/to/libfile.so");

    似乎即使您在dlopen 函数中使用绝对或相对路径,仍然会出现未找到目录的错误。我正在使用 CentOS,我的 Debian 也有这个问题。所以我认为神话提供的第一个解决方案是错误的。您可以在我上面提到的“调试”模式下进行验证。


    PS.2:如果您“安装”或“编译”共享库而不是通过包管理器安装它,则必须运行sudo ldconfig /path/where/not/found/shared/library/reside 以通知系统新添加的共享库。例如:

    cp /etc/ld.so.cache ~/ld.so.cache.backup    
    #cp -r /etc/ld.so.conf.d ~/ld.so.conf.d.backup #sometimes this backup is unnecessary.
    #cp /etc/ld.so.conf ~/ld.so.conf.backup #sometimes this backup is unnecessary.
    sudo ldconfig /PATH/WHERE/NOT/FOUND/SHARED/LIBRARY/RESIDE
    ###I am omitting the cp commands to roll back.
    ###For example, sudo cp -f ld.so.cache /etc/ld.so.cache
    

    要了解这里发生了什么,请仔细阅读上面链接中的所有内容。


    PS.3 : 您可以随时使用命令export LD_DEBUG=help,export LD_DEBUG=libs 找出-rpathLD_LIBRARY_PATH 如何解决您的问题。你会喜欢这种调试模式的。


    PS.4:找出问题所在的不那么残酷的方法:

    ldd ./YOURproblematicEXECUTABLE
    

    这个命令可以告诉你要打开的共享库是否位于。此外,有很多方法可以解决您的问题,每种方法都有其局限性和适用性。所以我强烈建议你阅读我上面提供给你的链接,并了解如何选择解决问题的方法。看完之后,如果你真的觉得自己很“OK”,也可以看看Better understanding Linux secondary dependencies solving with examples这个Better understanding Linux secondary dependencies solving with examples加深理解。

    【讨论】:

    • 这其实是一个很好的解释,点赞。
    【解决方案3】:

    dlopen 的声明看起来像, void *dlopen(const char *filename, int flag);

    如果您将 para 'filename' 设置为共享库的 name ,则应将当前路径添加到 'LD_LIBRARY_PATH' 中。例如,

    1, dlopen("libtest.so" , RTLD_LAZY)

    2、在 shell 中,导出 LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

    【讨论】:

      【解决方案4】:

      就我而言,解决方案非常简单:

      除非明确指定为相对路径,否则路径应为绝对路径

      所以我换了

      dlopen("mylib.so", RTLD_NOW)
      

      dlopen("./mylib.so", RTLD_NOW)
      

      问题解决了。

      【讨论】:

        【解决方案5】:

        我会推荐dlerror 来了解原因

        void* handle = dlopen(SO_FILE, RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND);
        if(handle == NULL)
        {
            printf(LOG_ERROR, "Error: %s\n",  dlerror());
            assert(0);
        }
        

        这将报告错误的详细原因

        【讨论】:

          猜你喜欢
          • 2021-11-30
          • 1970-01-01
          • 2015-04-12
          • 2018-11-26
          • 2019-11-27
          • 2020-02-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多