当前位置: 首页 > 面试题库 >

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

公良鸿禧
2023-03-14
问题内容

重新措词的问题(尽管已经解决):

我一直在使用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);

希望这可以更好地解释这种情况。


问题答案:

阅读dlopen(3)手册页(例如,通过man dlopen在计算机上键入终端):

如果filename包含斜杠(“
/”),则将其解释为(相对或绝对)路径名。否则,动态链接程序将按以下方式搜索库(有关更多详细信息,请参见ld.so(8)):

   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/等等....-或添加.到您的插件中LD_LIBRARY_PATH(出于安全原因,我不建议这样做)。

正如Jhonnash回答的那样,您应该使用并显示dlerrorwhendlopen(或dlsym)失败的结果:

  void* dlh = dlopen("./libLibraryName.so", RTLD_NOW);
  if (!dlh) 
    { fprintf(stderr, "dlopen failed: %s\n", dlerror()); 
      exit(EXIT_FAILURE); };

您可能需要阅读《高级Linux编程》等书籍,以大致了解有关Linux系统编程的知识。



 类似资料:
  • 当我从gradle/code中删除TensorFlow引用时,导入的模块可以正常工作。

  • 我试图在android Studio中向我的multidex项目添加一些lib(.jar&.so)。 当我只添加几个JAR到项目中时,所有的工作都很好。如果我添加了越来越多的JAR(其他库),我会得到以下错误: 有什么想法,我如何告诉编译器生成jar等在相同的dex?

  • 我在Visual Studio中创建了一个项目,2013年。 项目文件具有以下属性: ToolsVersion=“12.0”,PlatformToolset=v120。 我安装了Visual Studio 2013和Microsoft Build Tools 2015。此项目使用MSBuild 12.0成功构建。在试图构建它与MSBuild 14.0我得到一个错误 据我所知,问题在于变量VCTar

  • 问题内容: 我最近寻求帮助,它被拒绝投票并关闭(我不知道为什么) 事实证明,“ make install”-安装的make目标并暗示目标“ install-target-libstdc ++v3”实际上并不意味着您已准备就绪。 我一直想知道自己在做什么错了,因为我以为这样的make target可以帮到我。 我希望这个答案至少可以帮助其他人。 问题答案: 对于所有遇到类似问题的人,请运行以下命令:

  • 问题内容: (从Java-Selenium迁移到C#-Selenium) 当使用Selenium和C#搜索 显式等待时 ,我发现一些帖子的代码看起来类似于Java-Counterpart: 例如在这里: 或在这里: WebDriverWait来自OpenQA.Selenium.Support.UI命名空间,并位于一个单独的名为Selenium WebDriver支持类的程序包中 但是: 当我尝试在

  • 我已经安装了Python3.5并且在运行时 它给了我以下错误 我在路径中添加了以下行 我有一个64位的win7设置在我的电脑。 通过来减轻此错误并正确安装模块的解决方案是什么。