【问题标题】:Keeping variables global to the library scope in C在 C 中将变量保持在库范围内
【发布时间】:2010-10-19 20:08:47
【问题描述】:

有没有办法让全局变量只能在库内部可见,而不能从 C 中访问该库的程序访问?

保护变量并不是很重要,但如果程序无法导入它,我宁愿这样做,因为这与它们无关。

我不关心涉及宏的解决方案。

【问题讨论】:

  • 当你说可见时,你是指编译器还是链接器?

标签: c scope


【解决方案1】:

如果你使用 g++,你可以使用链接器工具来使用属性。

__attribute__((visibility("hidden"))) int whatever;

您还可以将所有内容标记为隐藏,并使用此标志明确标记可见的内容:-fvisibility=hidden

然后将可见变量标记为:

__attribute__((visibility("default"))) int whatever;

【讨论】:

  • 这是否适用于 GCC 而不是 G++?而且,在 C++ 中,您不会使用特定于库的命名空间(例如“命名空间 LibName::Private { ... }”)来保存库的私有变量。 (我的问题的部分答案是 MacOS X 上的 GCC 说 -fvisibility 与语言无关。)
  • 是的,它也可以与 gcc 一起使用,因为它与语言无关,它用于库中的符号,因此任何编译语言都应该接受 gcc。即使您在 c++ 中使用命名空间解决方案,该符号仍然是公共的,您可以从外部通过 LibName::Private::hiddenvar 访问它。
  • 注意:这是 GCC 4.x 的特性。
  • 我不确定我是否完全理解该属性的功能。让我重申你所说的以便更好地理解。基本上 __attribute__((visibility("hidden"))) 让您在 C 中拥有与 C++ 命名空间类似的功能?
  • 所以所有的库代码都将编译为 gcc 指定的“-fvisibility=hidden”?并且使用该库的所有代码都无法访问使用 __attribute__((visibility("hidden"))) 指定的任何全局变量?
【解决方案2】:
static int somelocalvar = 0;

这使得 somelocalvar 仅在声明它的源文件中可见 (reference and example)。

【讨论】:

  • 我知道,但变量必须是跨 lib 模块的全局变量。将所有内容塞进一个文件或使用函数不是一种选择。
  • 像这样的全局变量是设计缺陷的标志。如果我是你,我会重新考虑你想要做什么。
  • 我认为没有其他方法了。它就是那个或一个函数,而函数的开销是残酷的。这就是我问的原因。一整类函数的行为取决于知道该值。
  • 如果变量真的很重要,你应该重新组织库以考虑到这一点
【解决方案3】:

在库实现中,像这样声明你的变量:

struct my_lib_variables
{
  int var1;
  char var2;
};

现在在最终用户的标题中,这样声明:

struct my_lib_variables;

它将结构声明为不完整类型。将使用标头的人将能够创建指向结构的指针,但仅此而已。目标是他们必须写出这样的东西:

#include "my_lib.h"

struct my_lib_variables* p = my_lib_init();
my_lib_do_something(p);
my_lib_destroy(p);

库代码可以修改变量,但库不能直接修改。


或者您可以使用全局变量,但将 extern 声明放在最终用户不会使用的标头中。

【讨论】:

    【解决方案4】:

    您可以使用另一个头文件将功能导出到外部模块而不是内部功能,因此您不必声明不必从模块外部访问的全局变量。

    编辑: 如果您多次声明内容,则只有链接器问题。没有必要将所有全局数据保存在一个头文件中,事实上,为了可维护性和不同的责任区域,将其分成几个较小的部分可能是明智的。将外部数据和内部数据拆分为头文件就是这样的原因之一,这应该不是问题,因为可以在同一个源文件中包含多个头文件。并且不要忘记头文件中的守卫,这样可以避免链接中的冲突。

    #ifndef XXX_HEADER_FILE
    #define XXX_HEADER_FILE
    code
    #endif
    

    【讨论】:

    • 你仍然会遇到链接器冲突。
    猜你喜欢
    • 2011-03-26
    • 2015-12-18
    • 2014-08-22
    • 2020-03-25
    • 1970-01-01
    • 2020-03-20
    • 1970-01-01
    • 1970-01-01
    • 2015-04-21
    相关资源
    最近更新 更多