导出符号

C++中除了语言级别的访问特性(公有、私有和保护)外,还有两个相关的概念允许暴露API中的符号,它们位于物理层次,分别是:

  1. 外部链接
  2. 导出可见性

外部链接

外部链接这个术语是指一个编译单元中的一个符号可以被其他编译单元访问,而导出是只在库文件中可见的符号。只有外部链接才可以导出。
我们先看下外部链接,这是决定客户是否可以访问共享库中符号的第一步。特别地,除非采取强制措施,否则.cpp文件中(文件作用域)的全局自由函数和变量会有外部链接。
举个栗子:

// Uncomment the next line to prevent external linkage leakage
// namespace {// an integer constant with external linkage
int INTERNAL_CONSTANT = 42;// a string constant with external linkage
std::string Filename = "file.txt";// a non-static function with external linkage
void FreeFunction()
{cout << "Free function called" << endl;
}

上述代码中尽管已经将这些函数和变量限制在一个.cpp文件之内,然而机智的客户还是可以在自己的程序中访问这些符号,这样他们就能够不通过公有API直接调用全局函数并修改全局状态,从而破坏封装性。

// declare the external linkage elements of myobject.cpp
extern void FreeFunction();
extern int INTERNAL_CONSTANT;
extern std::string Filename;
// 不通过公有API调用私有函数和修改全局变量
// call a function hidden within the myobject.cpp module
FreeFunction();// access a constant defined within myobject.cpp
std::cout << "Internal constant = " << INTERNAL_CONSTANT << std::endl;// change global state within myobject.cpp
Filename = "different.txt";

对于以上外部链接泄露问题,有一下解决方法

  • 静态声明。预先考虑使用static关键字声明函数和变量。它将函数或变量指定为内部链接,从而不能在其所在的编译单元之外访问
  • 匿名命名空间。使用匿名命名空间更加符合C++的惯例用法,把文件作用域的函数和变量封装进匿名命名空间。这是一个更好的方法,因为它能够避免污染全局命名空间。可以按照如下方式实现:
namespace {int INTERNAL_CONSTANT = 42;std::string Filename = "file.txt";void FreeFunction(){cout << "Free function called" << endl;}
}

导出可见性

可以通过编译器特定的符号,指定共享库中哪些符号对外可见

  • Microsoft Visual Studio的DLL文件默认是不可访问的,必须显示声明哪些函数导出DLL才能对外可见。当需要导出时指定__desclspec(dllexport), 在客户端程序想要访问需要指定__desclspec(dllimport)才能访问符号。
  • GNU C++编译器默认情况下,所有符号对外可见。不过可以通过__attribute__可见性修饰符隐藏一个符号,当然GNU C++4.0以上可以通过__fvisibility_hidden标记,它强制所有声明在默认情况下隐藏可见性,个别符号需要声明__attribute__((visibility(“default”)))显示导出。使用__fvisibility_hidden还可以显著的提升动态库加载时的性能,并生成更小的库文件。

关注微信号,一起学习C++/go/vue

添加群一起讨论一起进步

C++库文件导出可见性相关推荐

  1. MS CRM2011库文件升级到CRM2015

    首先声明:CRM2011 无法直接升级到CRM2015,需要先升级到CRM2013 具体如下: Step 1:   准备将一个CRM2011的库文件直接升级到CRM2015 1,将CRM2011中的库 ...

  2. AD19 PCB设计导入元件库、导出pdf、定义板子形状、生成元件库、铺铜基本操作总结

    导入元件库 1.点击右侧components 2.右键,然后选择"Add or Remove Libraries." 3.点击从文件安装 4.选择库文件 导出PDF 导出原理图或者 ...

  3. C++中的库文件导入与导出

    前言 C++的库文件分为两种:lib文件和dll文件,前者是静态的,会在build时就被打包到exe内,单独的一个exe文件就可以运行,而后者是动态的,不会被打包到exe内,除了exe,还需要对应的d ...

  4. 三菱PLC编程软件GX WORKS3中如何自定义库文件FB并进行导出和导入库操作?

    三菱PLC编程软件GX WORKS3中如何自定义库文件FB并进行导出和导入库操作? 首先,我们要预先定义好自己的库文件FB,如下图所示,这里以简单的"启保停"为例进行说明: 我们需 ...

  5. matlab将脚本导出动态库文件.dll,并被python调用

    文章目录: 一.matlab将脚本生成动态库.dll文件 1.1 编写简单的脚本函数 1.2 生成dll文件 二.python调用.dll 所使用的的环境如下: 系统:windows10 matlab ...

  6. Linux编译时如何减小so库文件的大小

    Linux编译时如何减小so库文件的大小 今天问了我这个问题,我就顺便记录一下.客户问为什么libc.so文件再编译前和编译后的size不一样啊,staging 和 compile 两个dir下的 l ...

  7. automake生成静态库文件_动手 | 奶奶级的动态库入门

    程序编译过程 库文件 静态链接和动态链接的区别? 从0开始 - 创建和使用静态链接库 创建静态库项目 向静态库中添加文件 编译静态库 创建引用静态库的C++控制台应用 在应用中使用静态库功能 从0开始 ...

  8. 备忘: VC++ 自动适用编译两种模式库文件 (DLL, LIB)

    为什么80%的码农都做不了架构师?>>>    一个好的程序设计规划总会有属于自己的基础代码库.重用这些代码库,DLL或LIB方式最好的选择之一.在写新的项目或程序是,我们不可能每次 ...

  9. linux 环境变量文件_应急响应系列之Linux库文件劫持技术分析,有点硬核哟

    0×01 菜逼阶段 Linux库文件劫持这种案例在今年的9月份遇到过相应的案例,当时的情况是有台服务器不断向个可疑IP发包,尝试建立连接,后续使用杀软杀出木马,重启后该服务器还是不断的发包,使用net ...

最新文章

  1. RDC Hydrogen
  2. Java8函数式编程(3)--规约操作
  3. Bumblebee微服务网关之Url重写
  4. 如何删除虚拟机上的操作系统、删除新建的虚拟机
  5. python常用语法和示例_C语言切换案例教程,语法,示例和规则
  6. html滚动字幕如何向下移动,按向下键的同时,菜单选项向下移动,浏览器右边的滚动条也跟着跑怎么办。这个bug怎么改...
  7. Docker学习七:使用docker搭建Hadoop集群
  8. 不显示坐标刻度_Excel---不等距坐标刻度,你会吗?工作小技巧
  9. POJ - 3461 (kmp)
  10. JavaScript DOM高级程序设计 5动态修改样式和层叠样式表1(源代码)--我要坚持到底!...
  11. 3.3 神策数据分析平台
  12. Win10预览版已经支持WSL的带GUI的应用
  13. Android 不透明度 对应表
  14. office计算机高级应用,Office办公软件高级应用(大学计算机二级考试标准教程)...
  15. 运放_电流互感器电流检测电路
  16. 2020-09-07关皓
  17. 做自媒体视频变现的三大要素!
  18. win7系统缩小图片大小的详细步骤--win7w.com
  19. 赣南雪景美得像妖孽 让人窒息
  20. 关于urllib2.urlopen()的理解

热门文章

  1. hdu 1558(线段相交+并查集)
  2. 线段树杭电1754 I hate it
  3. NYOJ 586 疯牛 POJ 2456(二分搜索 + 贪心)
  4. 关键字之defer、panic、recover
  5. Vue 动态路由的实现以及 Springsecurity 按钮级别的权限控制
  6. 网络安全概念是什么?互联网时代它为何如此重要?
  7. ios 不同的数据类型转化为json类型
  8. (转)Mat, vectorpoint2f,Iplimage等等常见类型转换
  9. 关于VS AddIn的注册
  10. 面向对象三大特性,六个原则