【问题标题】:How to ask library to use its internal function in case same function exist in other libs如果其他库中存在相同的功能,如何要求库使用其内部功能
【发布时间】:2014-09-10 01:41:40
【问题描述】:

我有一个使用两个 libraries libA 和 libB 的 C 程序。问题是;这两个库都有 list_delete 函数,这是一个编译器错误。通过编写这些行,我能够成功编译和链接我的代码。

#undef list_delete
#define list_delete mysql_list_delete

在此之后,我可以在我的代码中调用 libA 的 list_delete 函数。但是,当我调用 libB 的任何函数(list_delete 除外)时,该函数在内部调用 list_delete 函数,而该函数恰好是 libA 的 list_delete 函数。

为什么? libB 应该在内部调用 list_delete 函数而不是 libA 的 list_function。

问题是我如何告诉 libB 库使用它自己的 list_delete 函数(请记住我的程序正在使用 libA 的 list_delete 函数)

【问题讨论】:

  • 您的库是静态的还是动态的(.dll、.so、.dylib)?一种方法是将 libB 的list_delete 声明为static。这将要求使用它的函数在同一个编译单元中,因为它的符号没有被导出。
  • 图书馆就是这样。我无法控制库,因为这些是第三方库

标签: c linker


【解决方案1】:

如果两个库都被静态链接到,就会发生这种情况。链接器在两个 obj 文件中都看到了 list_delete 符号,因此必须选择最终可执行文件中的符号。

为避免这种情况,您需要:

  1. 重新编写和重新编译一个或两个库,以便为各自的list_delete() 函数使用不同的名称。

  2. 将您的应用更改为动态链接到库而不是静态链接,这样它们就看不到彼此的功能并且不会再发生冲突了。

【讨论】:

  • 我不是这两个库的所有者,所以更改函数名称是不可能的。我将我的代码与 libA 静态链接,并与 libB 动态链接。
  • 如果 libB 是动态链接的,它是一个外部模块,因此不能调用静态链接到您的应用程序中的 libA 函数,除非 libB 本身在内部使用 libA,在这种情况下它将使用自己的libA 的副本,而不是您的应用使用的副本。
  • 这是我的理解,但 libB 正在调用 libA 函数。它只发生在 Linux(Ubuntu,gcc)上。相同的代码在 OSX 上运行良好
  • 抱歉,两个库都是动态链接的。
【解决方案2】:

使用带有 RTLD_DEEPBIND 的 dlopen 加载库解决了这个问题。

dlopen("libB", RTLD_LAZY | RTLD_DEEPBIND);

RTLD_DEEPBIND (since glibc 2.3.4) Place the lookup scope of the symbols in this library ahead of the global scope. This means that a self-contained library will use its own symbols in preference to global symbols with the same name contained in libraries that have already been loaded. This flag is not specified in POSIX.1-2001.

【讨论】:

    猜你喜欢
    • 2011-10-20
    • 2015-08-25
    • 2017-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-06
    相关资源
    最近更新 更多