【发布时间】:2010-10-19 20:08:47
【问题描述】:
有没有办法让全局变量只能在库内部可见,而不能从 C 中访问该库的程序访问?
保护变量并不是很重要,但如果程序无法导入它,我宁愿这样做,因为这与它们无关。
我不关心涉及宏的解决方案。
【问题讨论】:
-
当你说可见时,你是指编译器还是链接器?
有没有办法让全局变量只能在库内部可见,而不能从 C 中访问该库的程序访问?
保护变量并不是很重要,但如果程序无法导入它,我宁愿这样做,因为这与它们无关。
我不关心涉及宏的解决方案。
【问题讨论】:
如果你使用 g++,你可以使用链接器工具来使用属性。
__attribute__((visibility("hidden"))) int whatever;
您还可以将所有内容标记为隐藏,并使用此标志明确标记可见的内容:-fvisibility=hidden
然后将可见变量标记为:
__attribute__((visibility("default"))) int whatever;
【讨论】:
static int somelocalvar = 0;
这使得 somelocalvar 仅在声明它的源文件中可见 (reference and example)。
【讨论】:
在库实现中,像这样声明你的变量:
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 声明放在最终用户不会使用的标头中。
【讨论】:
您可以使用另一个头文件将功能导出到外部模块而不是内部功能,因此您不必声明不必从模块外部访问的全局变量。
编辑: 如果您多次声明内容,则只有链接器问题。没有必要将所有全局数据保存在一个头文件中,事实上,为了可维护性和不同的责任区域,将其分成几个较小的部分可能是明智的。将外部数据和内部数据拆分为头文件就是这样的原因之一,这应该不是问题,因为可以在同一个源文件中包含多个头文件。并且不要忘记头文件中的守卫,这样可以避免链接中的冲突。
#ifndef XXX_HEADER_FILE
#define XXX_HEADER_FILE
code
#endif
【讨论】: