我有一个链接到两个共享库的可执行文件,每个共享库都依赖于系统共享库。 (在这种情况下,这些是OpenCL和CUDA运行时库,但这不会影响问题)
+--> libA.so ---> libOpenCL.so (on system)
Exe -|
+--> libB.so ---> libcudart.so (on system)
Exe
以及libA.so
和libB.so
一起分发给用户。用户的系统上可能未安装libOpenCL.so
和/或libcudart.so
。
目标是Exe
应该无论如何都能启动,并在运行时检测到libA.so
无法加载,因为未满足其依赖性。
一种可能的方法是使它libA.so
在运行时使用dlopen()
进行加载,并在其中检测加载是否失败。
是否也可以正常地将libA.so
链接到Exe
,但是如果无法加载Exe
,以某种方式libA.so
仍然可以启动?在Linux和/或Windows平台上有可能吗?
答案 0 :(得分:5)
如果要执行此操作,则需要dlopen
。在程序加载时,除了执行失败外,没有其他用于错误报告的向量,对于如果缺少定义,打算在丢失的库中找到的符号将做出何种合理选择也没有合理的选择。
答案 1 :(得分:4)
在Windows上,您可以针对delay-loaded mode中可能缺少的DLL链接libA
和libB
。这将防止运行时系统在程序实际调用其功能之一之前加载DLL。
Linux没有开箱即用的延迟加载功能,但是您可以通过将libOpenCL.so
(或libcudart.so
)中的函数的虚拟包装器添加到libA
(或{{ 1}})。包装器将在初次调用时libB
需要库,然后跳转到实际函数实现。可以手动编写此类包装,也可以通过Implib.so自动生成此类包装:
dlopen
因此,# This will generate libOpenCL.tramp.S and libOpenCL.init.c
# which need to be linked into libA.
$ implib-gen.py libOpenCL.so
将不再直接与libA
链接,除非您调用使用OpenCL的函数,否则程序将正常运行。