设为首页 加入收藏

TOP

25.2.3 和C代码链接(1)
2013-10-07 15:36:08 来源: 作者: 【 】 浏览:75
Tags:25.2.3 代码 链接

25.2.3  和C代码链接(1)

在前面的例子中,我们假设您有可用的原始C语言代码。这个例子利用了一个事实,即大部分C语言代码都可以通过C++(www.cppentry.com)编译器成功编译。如果您只有编译后的C语言代码,可能是库的形式,那么您仍然可以在C++(www.cppentry.com)程序中使用这些代码,只不过需要一些额外的步骤。

为了实现函数重载,复杂的C++(www.cppentry.com)名称空间被"扁平化"了。例如,如果有一个C++(www.cppentry.com)程序,可以合法地编写:

  1. void MyFunc(double);  
  2. void MyFunc(int);  
  3. void MyFunc(int, int); 

然而这意味着链接器会看到几个不同的名称,所有名称都称为MyFunc,不知道您想调用哪一个。因此,所有C++(www.cppentry.com)编译器都执行了一项名为名称变异(name mangling)的操作,逻辑上等同于生成了以下名称:
  1. MyFunc_double  
  2. MyFunc_int  
  3. MyFunc_int_int 

为了避免和其他您可能定义的名称冲突,生成的名称通常都会包含一些对链接器合法但是对C++(www.cppentry.com)源代码不合法的字符。例如,Microsoft VC++(www.cppentry.com)生成的名称如下:
  1. MyFunc@@YAXN@Z  
  2. MyFunc@@YAXH@Z  
  3. MyFunc@@YAXHH@Z 

这种编码很复杂,而且通常是与特定厂商相关的。C++(www.cppentry.com)标准没有规定函数重载应该怎样在指定平台上实现,因此没有标准的名称变异算法。

在C语言中,函数重载是不受支持的(编译器会对重复定义报错)。因此,C编译器生成的名称是非常简单的,例如_MyFunc:

现在,如果您通过C++(www.cppentry.com)编译器编译一个简单的程序,即使这个程序只有一个MyFunc名称的实例,仍然会生成链接变异名称的请求。但是,当您和C语言库链接的时候,链接器找不到所需要的变异的名称,因此链接器会报错。因此,需要告诉C++(www.cppentry.com)编译器不要将名称变异。这是通过在两个头文件中通过extern "language"限定(为了指导客户代码创建一个和指定语言兼容的名称)的方式实现的,而且如果您的库源代码是用C++(www.cppentry.com)写的,还需要在定义的地方加上(为了指导库代码生成一个和指定语言兼容的名称)。

extern "language" 的语法如下所示:

  1. extern "language" declaration1();  
  2. extern "language" declaration2(); 

或:
  1. extern "language" {  
  2. declaration1();  
  3. declaration2();  

C++(www.cppentry.com)标准指出可以使用任何语言规范,所以编译器原则上能支持以下代码:
  1. extern "C" MyFunc(int i);  
  2. extern "FORTRAN" MatrixInvert(Matrix* M);  
  3. extern "Pascal" SomeLegacySubroutine(int n);  
  4. extern "Ada" AimMissileDefense(double angle); 
在实际中,许多编译器只支持"C"。每一个编译器厂商都会告诉您支持哪一些语言标记。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇25.2.3 和C代码链接(2) 下一篇25.2.6 混合C++使用Perl和shell脚..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·哈希表 - 菜鸟教程 (2025-12-24 20:18:55)
·MySQL存储引擎InnoDB (2025-12-24 20:18:53)
·索引堆及其优化 - 菜 (2025-12-24 20:18:50)
·Shell 中各种括号的 (2025-12-24 19:50:39)
·Shell 变量 - 菜鸟教 (2025-12-24 19:50:37)