总结:
我在一个库动态加载另一个库时遇到问题,我想知道编译器的差异是否是根本原因。
问题详情:
我的应用程序链接到动态加载 libpvrGBMWSEGL.so 的 libgbm.so,然后请求 gbm_backend 函数。
#libgbm.so
module = dlopen("/usr/lib/libpvrGBMWSEGL.so", RTLD_NOW | RTLD_GLOBAL)
dlsym(module, entrypoint)
当我尝试使用提供的符号时,它会抛出一个段错误。
分析:
libpvrGBMWSEGL.so 作为专有二进制 blob 提供。快速分析表明它是使用 Linaro GCC 5.3-2016.02 构建的
> strings libpvrGBMWSEGL.so | grep GCC
GCC: (Linaro GCC 5.3-2016.02) 5.3.1 20160113
同时,动态调用它的库 libgbm 是使用 Buildroot GCC 6.4.0 构建的
> strings libgbm.so | grep GCC
GCC: (Buildroot 2017.11-git-00884-g7af8140-dirty) 6.4.0
问题:
我是否应该期望这两个库在我使用它们的方式上兼容?
最佳答案
对于许多平台,都有一个已发布的 ABI 文档,编译器应遵守该文档。对于 C++ 和在这些平台 ABI 之上,有 Itanium C++ ABI (这与 Itanium 不再有任何关系,我认为它将是 Itanium 对计算的持久贡献)。
不过,这不会扩展到图书馆。 Linux 有很多 libc,针对 glibc 编译和链接的东西将无法在 Bionic libc (Android) 上运行,反之亦然,即使体系结构匹配。 C++ 标准库本质上也是如此(甚至 GCC 附带的实现也带有略微不同的 ABI 作为选项)。
对于 ARM,还有大量的子架构变体。
总结就是:当每个人都付出努力时,那么你努力去做的事情就会奏效。如果没有,可能不会。让 C++ 做到这一点比用 C 更难。
关于linux - 一个库(.so)可以动态加载另一个用不同编译器构建的库吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47212166/