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
dlopen failed: cannot open shared object file: No such file or directory
提问by user1534282
The problem is I use dlopen
to 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 是我写的,它不是系统库),但我得到了标题中显示的错误。
- I have included
dlfcn.h
- in compiler, I used the
-ldl
command - What I want to load is just the source code folder, I tried to add
-L.
, but it did not work.
- 我已经包括
dlfcn.h
- 在编译器中,我使用了
-ldl
命令 - 我要加载的只是源代码文件夹,我尝试添加
-L.
,但没有成功。
采纳答案by mythagel
If the library you want to dlopen is not in the standard search path you have a number of options:
如果您想要 dlopen 的库不在标准搜索路径中,您有多种选择:
Specify the full path to the file in dlopen
dlopen("/full/path/to/libfile.so");
Add the path to the library via LD_LIBRARY_PATH
LD_LIBRARY_PATH=/path/to/library/ ./executable
use the ld -rpath option to add a library path to the application.
g++ -link stuff- -Wl,-rpath=/path/to/library/
在 dlopen 中指定文件的完整路径
dlopen("/full/path/to/libfile.so");
通过 LD_LIBRARY_PATH 添加到库的路径
LD_LIBRARY_PATH=/path/to/library/ ./executable
使用 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 reset
command 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 dlopen
function, 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/reside
to 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=libs
to figure out how -rpath
or LD_LIBRARY_PATH
solve your problem. You will love this debugging mode.
PS.3 :您始终可以使用命令export LD_DEBUG=help
,export LD_DEBUG=libs
来找出-rpath
或LD_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二级依赖解决的例子,以加深理解。