我正在编写一个C(共享)库。它最初是一个翻译单元,我可以在其中定义几个static全局变量,以将其隐藏在外部模块中。
static
现在该库已扩展,我想将该模块分为几个较小的源文件。问题在于,对于上述全局变量,我现在有两个选择:
在每个源文件上都有私有副本,并通过函数调用以某种方式同步它们的值-这将非常丑陋,非常快。
删除static定义,以便使用extern- 在所有翻译单元之间共享变量,但是,如果在此处进行了必需的声明,则链接到库的应用程序代码现在可以访问这些全局变量。
extern
那么,是否有一种巧妙的方法可以使私有全局变量在多个特定的翻译单元之间共享?
您需要GCC 的可见性属性扩展。
实际上,类似:
#define MODULE_VISIBILITY __attribute__ ((visibility ("hidden"))) #define PUBLIC_VISIBILITY __attribute__ ((visibility ("default")))
(您可能想要#ifdef上面的宏,使用一些配置技巧àla autoconf和其他 自动工具 ;在其他系统上,您将只有空的定义,如#define PUBLIC_VISIBILITY /*empty*/etc …)
#ifdef
autoconf
#define PUBLIC_VISIBILITY /*empty*/
然后,声明一个变量:
int module_var MODULE_VISIBILITY;
或功能
void module_function (int) MODULE_VISIBILITY;
然后,您可以在共享库中使用module_var或调用module_function,但不能在外部使用。
module_var
module_function
另请参见GCC 的-fvisibility代码生成选项。
顺便说一句,您还-Dsomeglobal=alongname3419a6可以someglobal像往常一样编译和使用整个库;要真正找到它,您的用户将需要将相同的预处理器定义传递给编译器,并且可以使名称alongname3419a6随机且不太可能使冲突不太可能。
-Dsomeglobal=alongname3419a6
someglobal
alongname3419a6
PS。这种可见性 特定于GCC (可能还 特定于 ELF共享库, 例如Linux上的那些)。如果没有GCC或没有共享库,它将无法正常工作。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。也许其他一些编译器(clang来自LLVM)也可能支持 Linux上 的 共享库 (不是静态 库 )。实际上,真正的隐藏(针对单个共享库的多个编译单元)主要是由链接程序完成的(因为ELF共享库允许这样做)。
clang