仅在满足依赖关系时才加载共享库

Load shared library only if dependencies are met

我有一个 linked 到两个共享库的可执行文件,每个共享库都依赖于系统共享库。 (在这种情况下,这些是 OpenCL 和 CUDA 运行时库,但这不会影响问题)

     +--> libA.so  --->  libOpenCL.so (on system)
Exe -|
     +--> libB.so  --->  libcudart.so (on system)

Exe 连同 libA.solibB.so 一起分发给用户。用户可能没有在他们的系统上安装 libOpenCL.so and/or libcudart.so

目标是 Exe 无论如何都应该能够启动,并在运行时检测到,例如libA.so 无法加载,因为它的依赖项不满足。

一种可能性是使 libA.so 在运行时使用 dlopen() 加载,它会检测加载是否失败。

是否也可以正常 link libA.soExe,但如果 libA.so 无法启动,Exe 仍然可以启动加载?这在 Linux and/or Windows 平台上可行吗?

如果你想这样做,你需要 dlopen。在程序加载时,除了执行失败之外,没有用于错误报告的矢量,也没有任何合理的选择来确定要在丢失的库中找到的符号如果缺少定义将解析为什么。

在 Windows 上,您可以 link libAlibB 防止 delay-loaded mode 中可能丢失的 DLL。这将阻止 运行time 系统加载 DLL,直到您的程序实际调用其函数之一。

Linux 没有开箱即用的延迟加载功能,但您可以通过为 libOpenCL.so(或 libcudart.so)中的函数添加虚拟包装器来模仿它到 libA(或libB)。包装器 dlopen 在第一次调用时需要库并跳转到真正的函数实现。这样的包装器可以手工编写或通过 Implib.so:

自动生成
# This will generate libOpenCL.tramp.S and libOpenCL.init.c
# which need to be linked into libA.
$ implib-gen.py libOpenCL.so

因此 libA 将不再 link 直接针对 libOpenCL.so 并且您的程序将 运行 正常,除非您调用使用 OpenCL 的函数。