9

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

  1. 我已经包括dlfcn.h
  2. 在编译器中,我使用了-ldl命令
  3. 我要加载的只是源代码文件夹,我尝试添加-L.,但它不起作用。
4

5 回答 5

9

如果您要 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/

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

于 2012-10-12T02:07:38.760 回答
8

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

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=helpexport LD_DEBUG=libs找出-rpathLD_LIBRARY_PATH解决您的问题。你会喜欢这种调试模式。


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

ldd ./YOURproblematicEXECUTABLE

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

于 2018-03-03T13:10:34.527 回答
2

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

于 2012-10-12T02:10:07.217 回答
0

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

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

所以我换了

dlopen("mylib.so", RTLD_NOW)

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

问题解决了。

于 2022-02-03T08:47:42.050 回答
0

我会推荐dlerror来了解原因

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

这将报告错误的详细原因

于 2022-02-10T09:53:26.820 回答