【问题标题】:Hiding non-API symbols in library在库中隐藏非 API 符号
【发布时间】:2018-02-13 22:47:44
【问题描述】:

假设我有一个库 foo,它由模块 fooutil 组成,并具有以下源代码树:

foo/
    foo.c
    foo.h
    util.c
    util.h

库的公共 API 在 foo.h 中定义,所有全局标识符都正确地以 foo_util_ 为前缀。 util 模块仅供 foo 使用。为了防止与名为 util 的其他模块发生名称冲突,我想创建一个(静态)库,其中只有来自模块 foo 的标识符可见。我该怎么做?

编辑:我在互联网上进行了广泛的搜索,但令人惊讶的是,这似乎是计算机科学中那些未解决的问题之一。

【问题讨论】:

    标签: c posix ld static-linking object-files


    【解决方案1】:

    可能还有其他可能的方法,但这里有一个:

    您可以考虑将文件 util.c 包含在 foo.c 中,并使所有 util 函数/全局变量为静态。即:

    #include "util.c"
    // ...
    

    这与*.h 文件的工作方式相同,它只是将整个源代码移植到foo.c,嵌套util.c 并使所有静态数据可用。

    当我这样做时,我将文件重命名为.inc(即util.c => util.inc)...

    #include "util.inc"
    // ...
    

    ...这是我在某处找到的旧约定,虽然它可能与汇编文件冲突,所以您必须自行决定。

    编辑

    另一种方法可能需要链接器特定的指令。例如,this SO answer details GNU's ld to achieve this goal。同一个线程中还列出了其他方法。

    【讨论】:

    • 这是一个有趣的方法。但是,我更喜欢在目标文件级别工作的解决方案。
    • @AugustKarlstrom 我完全可以理解这种偏好。但是,我认为这将是链接器特定的解决方案。我用详细信息编辑了我的答案。
    • 您链接到的 GNU ld 方法需要手动管理导出符号的文件。我应该可以说 util.o 中的所有符号都应该被隐藏。
    • @AugustKarlstrom 我链接到的同一个线程也提供了一些其他方法。但是,我认为无论编译器还是链接器都可以使用的唯一可移植方法最终是#include 方法。就个人而言,我以gccclang 为目标,因此我可以轻松地使用非便携式功能。
    【解决方案2】:

    以下是 GCC 特定的。

    您可以用

    标记每个实用程序功能
    __attribute__((visibility ("hidden")))
    

    这将阻止它从另一个共享对象链接到。

    您可以将其应用于一系列声明,方法是用

    包围它们
    #pragma GCC visibility push(hidden)
    /* ... */
    #pragma GCC visibility pop
    

    或者在编译对象时使用-fvisibility=hidden,这适用于没有明确可见性的声明(例如,既不是__attribute__((visibility))也不是#pragma GCC visibility)。

    【讨论】:

      【解决方案3】:

      util.h 中的每个变量和函数声明之前,定义一个宏常量,通过添加库前缀foo_ 来重命名声明的标识符,例如

      #define util_x foo_util_x
      extern int util_x;   
      
      #define util_f foo_util_f
      void util_f(void);
      
      ...
      

      有了这些定义,就不需要更改代码的其他部分,并且目标文件util.o 中的所有全局符号都将以foo_ 为前缀。这意味着名称冲突不太可能发生。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-28
        • 1970-01-01
        • 1970-01-01
        • 2021-11-04
        • 2012-07-06
        • 2012-11-27
        • 2021-08-26
        • 2011-10-07
        相关资源
        最近更新 更多