【问题标题】:The common ways of resolving C naming collision解决C命名冲突的常用方法
【发布时间】:2021-12-21 00:39:35
【问题描述】:

我有两个静态库(比如 A 和 B),它们都通过直接独立地包含源文件来引用相同的第三方库(比如 C)。 C 非常简单,只有一个 .h 和 .c 文件。可执行文件 D 与 A 和 B 链接。

假设 C 中有一个函数 fn。当可执行文件 D 解析函数名称:fn 时,它会在 A 或 B 中选择任意 fn 实现。

我的问题是如何确保 A 中的代码引用 A 的 C 实现而 B 引用 B 的 C 实现?

由于 C 是第三方库,所以我不会修改 C 的代码。因此,重命名任何一个函数都不起作用。我曾经考虑过使用 C++ 的命名空间来包装 C 的代码,如下所示

namespace WRAP
{
#include "moudule_c_source_file.c"
}

但是,由于 module_c_souce_file.c 包含 module_c_source_file.h,其中包含 extern "C" 声明。这会导致生成的符号对象文件不包含命名空间信息。这样可执行 D 仍然链接任意函数实现。

在不接触第三方库代码的情况下解决我上面提到的问题有什么想法吗?

【问题讨论】:

  • 您可以使用一堆#defines 来有效地重命名您的C 库中的外部名称。
  • 由于“一个定义规则”,使用哪个库并不重要。否则你的程序会调用未定义的行为
  • 这些是静态库还是动态库?在哪个操作系统上?
  • @AlanBirtles A 和 B 是静态库,C 实际上是一个 .h 和一个 .c 文件,直接添加到 A 和 B 中。操作系统:Windows

标签: c++ c linker


【解决方案1】:

以下想法的可能性取决于第三方库的大小。我唯一的想法是创建自己的中间层库。比如mid-layer-library-A.dll使用A,mid-layer-library-B.dll使用B。所以mid-layer-library-A.dll从A导入fn,导出mid_A_fn,mid-layer -library-B.dll 从 B 导入 fn 并导出 mid_B_fn。可执行文件 D 链接到中间层库和 C。因此,D 具有三种不同的方法:mid_A_fn、mid_B_fn 和来自 C 的 fn。 类似于设计模式“适配器”。

【讨论】:

    【解决方案2】:

    当可执行文件 D 解析函数名 fn 时,它会在 A 或 B 中选择任意 fn 实现。

    不,它没有。它选择可用的第一个定义,哪个定义取决于Ds 链接行上AB 的顺序。

    如何确保 A 中的代码引用 A 的 C 实现,B 引用 B 的 C 实现?

    在您描述的场景中,D 将包含一个单个 定义(来自AB),因此您的问题毫无意义。

    此外,由于fn相同,使用哪个定义无关紧要

    如果fns 实际上并不相同,则说明您违反了 ODR,并且您的二进制文件具有未定义的行为。

    【讨论】:

      猜你喜欢
      • 2011-01-31
      • 1970-01-01
      • 2015-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-25
      • 1970-01-01
      相关资源
      最近更新 更多