如何加载共享库而不加载其依赖项?
假设我有一个库 libfoo.so.1
,它依赖于(根据 ldd
)libbar.so.1
。但是,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_LIBRARY_PATH
或ldconfig
中>,其依赖项均已解析libfoo.so.1
,这是一个共享库,位于与libbar
不同的目录中,但它依赖于libbar
。在运行时,libfoo
将知道在哪里定位libbar
。App
,一个二进制应用程序,需要在运行时的某个时刻加载libfoo
。
App
不知道在哪里可以找到 libbar
,但知道 libfoo
知道。我想要完成的是在 libfoo
中有一个 init 函数,它只会将 App
的当前工作目录更改为 libbar
所在的位置最终解决所有依赖关系并让每个人都满意。
libfoo
最终需要调用libbar
中的内容,而不是在此 init 函数中。我认为创建存根不起作用,因为符号最终需要解析为真实函数。
Say I have a library libfoo.so.1
, which depends (according to ldd
) on libbar.so.1
. However, libbar.so.1
is not available at the moment. My app needs to call a function in libfoo.so.1
which doesn't require libbar.so.1
at all.
Is there a way to load libfoo.so.1
, resolve the function symbol and then call it without having libbar.so.1
to satisfy the dependency? It's a case of "I know what I'm doing, just let me do it already". I tried the RTLD_LAZY flag, but it still tries to load the libbar.so.1
library before not loading the symbols.
EDIT
Here's the exact situation.
We have 3 players:
libbar.so.1
, a shared library located in a path not inLD_LIBRARY_PATH
orldconfig
, and whose dependencies are all resolvedlibfoo.so.1
, a shared library located in a different directory thanlibbar
, but which depends onlibbar
. At runtime,libfoo
will know where to locatelibbar
.App
, a binary application which needs to loadlibfoo
at some point during runtime.
App
doesn't know where to find libbar
, but knows that libfoo
knows. What I'm trying to accomplish is having an init function in libfoo
which would simply change App
's current working directory to where libbar
is located to finally resolve all the dependencies and make everyone happy.
libfoo
will eventually need to call stuff in libbar
, just not in this init function. I don't think creating a stub would work since the symbols would eventually need to resolve to the real functions.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
好吧,即使使用 RTLD_LAZY 变量仍然可以解析,所以一般来说您确实需要链接所有库。似乎您应该创建一个没有任何功能且可由链接器找到的存根
libbar.so.1
。Well, variables are still resolved even with
RTLD_LAZY
, so in general you do need all the libraries to be linked. Seems like you should create a stublibbar.so.1
that has no functionality and can be found by the linker.只是一个想法,您是否考虑过插入依赖项 - 只需创建一个具有相同签名、参数等的相同函数,然后让链接器解析该函数并忽略 libbar.so.1?既然你没有提到这一点,我想我会建议这个。
希望这有帮助,
此致,
汤姆.
Just a thought, have you thought of interpositioning dependency - simply create a identical function with the same signature, parameters etc and let the linker resolve this function and ignore libbar.so.1? Since you did not mention this, I thought I'd suggest this.
Hope this helps,
Best regards,
Tom.
另一个想法:从
libfoo.so.1
中提取(使用 ar(1))必要的函数,将其提取到.o
或另一个中.so
文件,然后链接该提取帮助?我假设对 libbar.so.1 的引用位于 libfoo 函数中,该函数不会从您的程序调用(即使是间接调用)。Another thought: Would extracting (use ar(1)) the necessary function(s) from
libfoo.so.1
, either into a.o
or into another.so
file, and then linking against that extract help? I'm assuming the reference tolibbar.so.1
is in a libfoo function that is not called (even indirectly) from your program.这里的实际需求是什么?仅仅链接一个库并没有多大作用,而且通常是良性的。你缺图书馆吗?只需创建一个同名的存根库即可。您想控制或抢占库中符号的使用吗?将它们放在另一个库中(带有正确的版本标签!)并 LD_PRELOAD 它。
我想这里的元问题是我不明白能够抢占依赖关系有什么价值。这只是一个辅助功能。
What's the actual requirement here? Merely linking a library doesn't do much, and is usually benign. Do you lack the library? Just create a stub library of the same name. You want to control or preempt the use of symbols in the library? Put them in another library (with the right version tags!) and LD_PRELOAD it.
I guess the meta-question here is that I don't see what value being able to preempt the dependency linkage has. It's just a helper function.
使用 dlopen 加载库并使用 dlsym 获取所需的函数。
Use dlopen to load the library and dlsym to get the function you need.