【问题标题】:How to use shared libraries in a static library without forcing end-users to link against these?如何在静态库中使用共享库而不强制最终用户链接这些库?
【发布时间】:2012-07-06 21:20:58
【问题描述】:

假设我正在开发一个静态库foo.a,它使用了bar.so 中的一个函数。

我如何构建这个库,使得在他们的项目中使用foo.a 的任何人都不必明确链接到bar.so

【问题讨论】:

  • 我知道这是可能的,因为 SFML 不需要我链接 -lX11 或 -lGL。
  • 我很确定,你不能这样做,除非你得到一个 bar 的静态库,例如你的例子 - bar.a (正如我在你的另一个问题中已经说过的,我无法提供更多信息,因为我不熟悉 SFMLXLib)
  • 你的目标是什么?您是否只想避免在链接时引用bar.so,因为这样更方便?或者您是否希望能够在不重新链接的情况下将bar.so 替换为someother.so
  • 不,我希望人们不需要链接到 -lGL、-X11 和我需要使用的任何其他动态库。
  • 在这种情况下,user315052 提到的dlopen 是一个矫枉过正的 IMO。您获得的东西几乎不值得额外的编码工作和可维护性问题。最好坚持使用额外的链接器选项,没有简单的方法可以避免它们。

标签: c++ static-linking dynamic-linking


【解决方案1】:

您可以在libfoo.a 中执行的操作是调用dlopen 以动态链接libbar.so。然后,使用dlsym 定位您要使用的功能。

typedef void (*BarFunctionType) (const char *);
FunctionType barFunction;

void initialize_foo_lib () {
    void *h = dlopen("libbar.so", RTLD_LAZY);
    BarFunctionType barFunction = (BarFunctionType) dlsym(h, "barFunction");
    // Note scary looking cast to get your function pointer.
    //... rest of code can call barFunction now
}

libbar.so 应该是 C 库,或者函数应该是 extern "C" 如果是 C++ 库,以便您正确找到函数名称。否则,您将需要修改名称才能找到带有dlsym 的函数。您可以在库上使用objdump -T 来检查库中的名称是否被损坏。

意识到仍然存在对 libbar.so 的依赖,但它已被烘焙到您的静态库中。所以libfoo.a的用户在链接-lfoo时不必在链接行中添加-lbar

【讨论】:

    【解决方案2】:

    从扩展来看,你正在寻找一种 Unix 方式;据我所知,g++ 和 clang++ 都无法做到这一点。

    Visual C++ 或许可以做到——我只将它用于静态库,而不是 DLL,但是...

    【讨论】:

      猜你喜欢
      • 2011-05-24
      • 2023-04-04
      • 2012-06-06
      • 2011-01-25
      • 1970-01-01
      • 2011-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多