当前位置:嗨网首页>书籍在线阅读

09-控制符号的可见性

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

42.2 控制符号的可见性

设计良好的共享库应该只公开那些构成其声明的应用程序二进制接口(ABI)的符号(函数和变量),其原因如下。

  • 如果共享库的设计人员不小心导出了未详细说明的接口,那么使用这个库的应用程序的作者可能会选择使用这些接口。这样在将来升级共享库时可能会带来兼容性问题。库的开发人员认为可以修改或删除那些不属于文档中记录的ABI中的接口,而库的用户则希望继续使用名称与他们当前正在使用的接口名称一样的接口(同时语义保持不变)。
  • 在运行时符号解析阶段,由共享库导出的所有符号可能会优先于其他共享库提供的相关定义(参见41.12节)。
  • 导出非必需的符号会增加在运行时需加载的动态符号表的大小。

当库的设计人员确保只导出那些库的声明的ABI所需的符号就能使上述问题发生的可能性降到最低或避免上述问题的发生。下列技术可以用来控制符号的导出。

  • 在C程序中可以使用static关键词使得一个符号私有于一个源代码模块,从而使得它无法被其他目标文件绑定。

除了使一个符号私有于源代码模块之外,static关键词还能达到一个相反的效果。如果一个符号被标记为static,那么在同一源文件中对该符号的所有引用会被绑定到该符号的定义上,其结果是这些引用在运行时不会被关联到其他共享库中的相应定义上(以41.12节中描述的方式)。static关键词的这种效果类似于41.12节中介绍的链接器选项,但差别在于static关键词只影响单个源文件中的单个符号。

  • GNU C编译器gcc提供了一个特有的特性声明,它执行与static关键词类似的任务。

1093.png static关键词将一个符号的可见性限制在单个源代码文件中,而hidden特性使得一个符号对构成共享库的所有源代码文件都可见,但对库之外的文件不可见。

与static关键词一样,hidden特性也能达到一个相反的效果,即防止在运行时发生符号插入。

  • 版本脚本(参见42.3节)可以用来精确控制符号的可见性以及选择将一个引用绑定到符号的哪个版本。
  • 当动态加载一个共享库时(参见42.1.1节),dlopen()接收的RTLD_GLOBAL标记可以用来指定这个库中定义的符号应该用于后续加载的库中的绑定操作,– –export–dynamic链接器选项(参见42.1.6节)可以用来使主程序的全局符号对动态加载的库可用。

更多有关符号可见性方面的细节信息可以参见[Drepper, 2004 (b)]。