【问题标题】:Is there a way to limit the use of a function to its library in C?有没有办法将函数的使用限制在 C 中的库中?
【发布时间】:2021-10-10 16:19:44
【问题描述】:

所以我正在为一个学校项目开发一个静态 C 库(如 library.a 文件)。有多个函数,其中一些放在不同的文件中,所以我不能使用static关键字。有没有办法将这些功能限制在库本身,相当于库的static

【问题讨论】:

  • “图书馆”到底是什么意思?
  • 一个静态库,如library.a 文件
  • 在C中,函数只有一个命名空间;通常,前缀用于描述库的公共功能?
  • 我猜你想要 hiddeninternal 可见性之类的东西,尽管我认为它对于 .a 库的效果不如 @987654330 那样好@

标签: c


【解决方案1】:

所以我正在为一个学校项目开发一个静态 C 库(如 library.a 文件)。有多个函数,其中一些放在不同的文件中,所以我不能使用static关键字。有没有办法将这些功能限制在库本身,相当于库的static

C 语言没有任何形式意义上的程序组织单元大于单个翻译单元但小于整个程序。库是语言规范的一个外来概念,基本上由所有工具链提供,但不是语言本身的一部分。 因此,不,C 语言没有定义除 static 之外的机制来声明函数标识符只能由为程序做出贡献的所有翻译单元的适当子集引用。

某些共享库格式(例如 ELF)支持此类限制,针对此类共享库的 C 实现通常会提供扩展以启用这些设施,但对于静态库通常并非如此。

还要注意,在所有这些情况下,我们讨论的是函数标识符链接,而不是真正控制对函数的访问。原则上,程序中的任何函数都可以通过指向它的函数指针从程序中的任何位置调用。


框架挑战:你为什么在乎?

如果您不希望库客户端直接调用具有外部链接的函数,通常的解决办法是从库的公共头文件中省略这些函数。如果某个勇敢的人可以分析库以发现并可能调用这些函数,那又有什么关系呢?您的公共标头和文档告诉人们应该如何使用该库。如果人们以其他方式使用它,那是他们的责任。

【讨论】:

  • 如果某个勇敢的人可以分析库以发现并可能调用这些函数,这有什么关系?您不希望任何人直接使用功能,因为这可能意味着您永远无法修改该功能。 您的公共标头和文档告诉人们应该如何使用该库。如果人们以其他方式使用它,那是他们的责任。 如果他们是重要客户,则不会:“哦,不!你不能改变它!我们正在使用它!看!我们得到了你的副总裁销售同意我们!”最好永远不要让他们有机会对你这样做...... ;-)
  • (cont) 你暴露的越少,名字冲突的可能性就越小。
  • 放入合同中。不允许他们使用内部函数,即以my_lib_internal_ 开头的函数,如果他们这样做,您不承担任何责任。
  • @bolov “看,我们甚至让你的副总裁同意更改合同!”如果从合同谈判中移除 4 个级别的技术实施者甚至可以首先决定合同条款......
  • +1 表示“您的公共标头和文档告诉人们应该如何使用该库。如果人们以其他方式使用它,那么就在他们身上。”我完全同意这种说法。
【解决方案2】:

如果它们是使用外部链接定义的,则可能无法从其他源文件中完全“隐藏”一组受限函数的存在,因为它们的标识符在链接时将可见(如其他答案中所述)。

但是,如果您只是想防止某人无意中调用受限函数,则以下方法之一可能有用:

  1. 在我的一些项目中,我使用了#define#ifdef 语句来阻止在整个程序中使用受限函数。例如,在我的硬件抽象层 (HAL) 库 C 源文件中,我通常将 #define HAL__ 放在任何 #include 语句之前。然后我在头文件中的任何受限函数定义周围放置一个#ifdef HAL__ ... #endif 块。有意图的人可以通过在其源代码中添加#define HAL__ 或修改头文件轻松绕过此问题,但它提供了一些保护,防止无意使用受限函数和其他定义。
  2. 将受限函数定义放在用于构建库本身的单独头文件中(例如library.a),并仅提供包含非受限函数声明的头文件。定义的任何函数的标识符仍然对链接器可见,但没有原型,任何人都很难调用它们。

同样,如果在整个程序中显示任何受限功能的标识符将是一个问题(例如,复制其他标识符),那么这些选项将不起作用。此外,如果目标是防止开发人员故意调用受限函数,那么这些选项将不起作用,尽管选项 2 会使这变得更加困难。如果目的只是为了防止对受限函数的无意调用,并且不担心程序中有重复的标识符,那么这些选项可能会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-16
    • 2019-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多