Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何加载共享库而不加载其依赖项?_C_Linux_Shared Libraries_Elf - Fatal编程技术网

C 如何加载共享库而不加载其依赖项?

C 如何加载共享库而不加载其依赖项?,c,linux,shared-libraries,elf,C,Linux,Shared Libraries,Elf,假设我有一个库libfoo.so.1,它依赖于libbar.so.1(根据ldd)。但是,libbar.so.1目前不可用。我的应用程序需要调用libfoo.so.1中的函数,该函数根本不需要libbar.so.1 有没有一种方法可以加载libfoo.so.1,解析函数符号,然后在没有libbar.so.1的情况下调用它来满足依赖关系?这是一个“我知道我在做什么,就让我去做吧”的例子。我尝试了RTLD_LAZY标志,但它仍然尝试在不加载符号之前加载libbar.so.1库 编辑 具体情况如下

假设我有一个库
libfoo.so.1
,它依赖于
libbar.so.1
(根据
ldd
)。但是,
libbar.so.1目前不可用。我的应用程序需要调用
libfoo.so.1
中的函数,该函数根本不需要
libbar.so.1

有没有一种方法可以加载
libfoo.so.1
,解析函数符号,然后在没有
libbar.so.1
的情况下调用它来满足依赖关系?这是一个“我知道我在做什么,就让我去做吧”的例子。我尝试了RTLD_LAZY标志,但它仍然尝试在不加载符号之前加载
libbar.so.1


编辑

具体情况如下

我们有3名球员:

  • libbar.so.1
    ,一个位于路径中的共享库,该路径不在
    LD\u library\u path
    ldconfig
    中,并且其依赖关系都已解决
  • libfoo.so.1
    ,一个共享库,位于与
    libbar
    不同的目录中,但它依赖于
    libbar
    。在运行时,
    libfoo
    将知道在哪里找到
    libbar
  • App
    ,一个二进制应用程序,需要在运行时的某个点加载
    libfoo
App
不知道在哪里可以找到
libbar
,但知道
libfoo
知道。我试图实现的是在
libfoo
中有一个init函数,它可以简单地将
App
的当前工作目录更改为
libbar
所在的位置,从而最终解决所有依赖项,让每个人都满意


libfoo
最终需要在
libbar
中调用stuff,而不是在这个init函数中。我认为创建存根是行不通的,因为符号最终需要解析为实际函数。

好吧,即使使用
RTLD\u LAZY
,变量仍然可以解析,所以一般来说,您确实需要链接所有库。似乎您应该创建一个存根
libbar.so.1
,它没有任何功能,可以被链接器找到。

只是一个想法,您是否想过插入依赖项-只需创建一个具有相同签名、参数等的相同函数,让链接器解析此函数并忽略libbar。那么。1?既然你没有提到这一点,我想我会提出这个建议

希望这有帮助, 顺致敬意,
Tom。

使用dlopen加载库并使用dlsym获取所需的函数。

另一个想法是:从
libfoo.so.1
中提取(使用ar(1))必要的函数,或者将其加载到
.o
或另一个
.so
文件中,然后链接到该提取帮助?我假设对libbar.so.1的引用在一个libfoo函数中,而这个函数不是从程序中调用的(甚至是间接调用的)。

这里的实际需求是什么?仅仅链接一个库并没有多大作用,而且通常是良性的。你缺少图书馆吗?只需创建一个同名的存根库。是否要控制或抢占库中符号的使用?将它们放在另一个库中(使用正确的版本标记!),然后LD_预加载它


我想这里的元问题是,我看不出能够抢占依赖链接有什么价值。这只是一个帮助函数。

很好,你提到了RTLD_LAZY,这表明你已经尝试过了,并且阻止了我走上建议它的歧途。我认为这是行不通的。每个库都有一个在链接时编码到其中的依赖项列表,该列表独立于未定义的符号集。加载程序将尝试查找这些依赖项,无论它们是否实际需要。@Jay:加载程序的路径嵌入到可执行文件中,以便动态加载函数……我想通过指定具有相同签名的重复函数来防止动态加载,从而迫使链接器使用该函数版本改为…@Jay:刚刚看到你对Adam的回答的反应,那是我的想法…一个存根,因为没有更好的词…@tommieb75,那就好了。符号被定义在哪里并不重要,只要它们被定义在某个地方。尽管libbar.so仍然必须存在,即使它是空的。我认为这会起作用,但您需要存根来定义libfoo.so所依赖的所有符号。但是定义本身可以是存根。正如tommieb75指出的,存根实际上不必在libbar中。因此,它们的符号必须在某个地方定义。我认为您不需要定义所有符号,这不是
RTLD\u LAZY
所能做的吗?
RTLD\u LAZY
仅仅是建议。可能是由于某些事情可能超出了您的控制范围,因此会被忽略(例如,不支持延迟绑定的系统、已启动的程序suid或出于安全或健壮性目的禁用延迟绑定的管理员配置);当库在启动时被链接时,您不需要指定它。实际上,动态库不是
ar
chives。