Linux dlopen 失败:无法打开共享对象文件:没有这样的文件或目录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12851184/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 14:35:27  来源:igfitidea点击:

dlopen failed: cannot open shared object file: No such file or directory

linux

提问by user1534282

The problem is I use dlopento load a library (the .so is written by me, it's not a system library), but I got the error shown in the title.

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

  1. I have included dlfcn.h
  2. in compiler, I used the -ldlcommand
  3. What I want to load is just the source code folder, I tried to add -L., but it did not work.
  1. 我已经包括 dlfcn.h
  2. 在编译器中,我使用了-ldl命令
  3. 我要加载的只是源代码文件夹,我尝试添加-L.,但没有成功。

采纳答案by mythagel

If the library you want to dlopen is not in the standard search path you have a number of options:

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

  1. Specify the full path to the file in dlopen

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

  2. Add the path to the library via LD_LIBRARY_PATH

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

  3. use the ld -rpath option to add a library path to the application.

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

  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/

Note that options 1 & 3 hardcode the library path into your application. -rpath does have an option to specify a relative path, i.e.

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

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

Will embed a relative path into the application.

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

回答by bbg

the dlopen's declaration look like, void *dlopen(const char *filename, int flag);

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

if you set the para 'filename' as shared library's name , you should add you current path into the 'LD_LIBRARY_PATH'.for instance,

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

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

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

2, in shell , export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

2、在shell中,export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

回答by Han XIAO

The most brutal and effective way to find out where your code goes wrong is the following command which will activate the debugging mode for shared libraries and is documented here:

找出代码哪里出错的最粗暴和有效的方法是以下命令,它将激活共享库的调试模式,并记录在此处

export LD_DEBUG=libs

Then, you will be surprised that so much information pops up. Don't worry, these information tells you which shared libraries the command you just typed needs and where to locate these needed libraries. For example, if you type reset, the screen will be reseted and then information about the shared libraries resetcommand needs will be printed.

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

Then, execute your "problematic" executable to see what's going wrong.

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



PS.1 : According to your accepted mythagal's solution :

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

Specify the full path to the file in dlopen

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

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

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

It seemed that even though you use absolute or relative path in the dlopenfunction, the directory not found error will still show up. I am using CentOS, and my Debian is also having this problem. So I think the first solution mythagal provide is wrong. You can verify that in the "debugging" mode I mentioned above.

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



PS.2: If you "install" or "compile" a shared library rather than install it through package manager, you MUST run sudo ldconfig /path/where/not/found/shared/library/resideto notify the system of the newly added shared library. For example :

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

To understand what's going on here, please carefully read all the contents in the link above.

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



PS.3 : You can always use the command export LD_DEBUG=help,export LD_DEBUG=libsto figure out how -rpathor LD_LIBRARY_PATHsolve your problem. You will love this debugging mode.

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



PS.4: A less brutal way to figure out what's going wrong:

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

ldd ./YOURproblematicEXECUTABLE

This command can tell you whether your shared library to be opened is located or not. Besides, there are so many ways to fix your problem and each way has its limitation and application. So I strongly suggested you read the link I provide you above and understand how to choose the way to solve your problem. After reading that, if you actually feel like being very "OK", you can also read this Better understanding Linux secondary dependencies solving with examplesfor deeper understanding.

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