C++中extern "C"的设立动机是实现C++与C及其他语言的混合编程。

       C++为了支持函数的重载,C++对全局函数的处理方式与C有明显的不同。对于函数void foo( int x, int y );该函数被C编译器编译后在符号库中的名字为_foo。而C++编译器则会产生像_foo_int_int之类的名字。

     extern是C/C++语言中表明函数和全局变量作用范围(可见性)的keyword,该keyword告诉编译器。其声明的函数和变量能够在本模块或其他模块中使用。

  通常,在模块的头文件里对本模块提供给其他模块引用的函数和全局变量以keywordextern声明。
       比如,假设模块B欲引用该模块A中定义的全局变量和函数时仅仅需包括模块A的头文件就可以。这样,模块B中调用模块A中的函数时。在编译阶段,模块B尽管找不到该函数,可是并不会报错;它会在连接阶段中从模块A编译生成的目标代码中找到此函数。

  与extern相应的keyword是static,被它修饰的全局变量和函数仅仅能在本模块中使用。因此。一个函数或变量仅仅可能被本模块使用时,其不可能被extern “C”修饰。

  被extern "C"修饰的变量和函数是依照C语言方式编译和连接的。

比如:如果在C++中:

// 模块A头文件 moduleA.h

int foo( int x, int y );
在模块B中引用该函数:

// moduleB.cpp

#include "moduleA.h"

foo(2,3);


  实际上,在连接阶段,连接器会从模块A生成的目标文件moduleA.obj中寻找_foo_int_int这种符号!
加extern "C"声明后,模块A的头文件变为:

// 模块A头文件 moduleA.h

extern "C" int foo( int x, int y );
在模块B的实现文件里仍然调用foo( 2,3 ),其结果是:

  (1)模块A编译生成foo的目标代码时,没有对其名字进行特殊处理,採用了C语言的方式。

  (2)连接器在为模块B的目标代码寻找foo(2,3)调用时,寻找的是未经改动的符号名_foo。
  假设在模块A中函数声明了foo为extern "C"类型,而模块B中包括的是extern int foo( int x, int y ) ,则模块B找不到模块A中的函数;反之亦然。
在C语言的头文件里,对其外部函数仅仅能指定为extern类型。C语言中不支持extern "C"声明,在.c文件里包括了extern "C"时会出现编译语法错误。在C中引用C++语言中的函数和变量时。C++的头文件需加入extern "C",可是在C语言中不能直接引用声明了extern "C"的该头文件,应该仅将C文件里将C++中定义的extern "C"函数声明为extern类型。

比如:

//C++头文件 a.h

extern "C" int foo( int x, int y );
//C++实现文件 a.cpp

#include "a.h"

int foo( int x, int y ){return x + y;}
/* C实现文件 b.c

这样会编译出错:#include "a.h" */

extern int foo( int x, int y );

int main( int argc, char* argv[] ){
       foo( 2, 3 );
       return 0;
}


extern "C" 的含义:实现C++与C及其他语言的混合编程的更多相关文章

  1. [收藏转贴]struct探索·extern "C"含义探索 ·C++与C的混合编程·C 语言高效编程的几招

    一.C/C++语言 struct深层探索 1.自然对界 struct是一种复合数据类型,其构成元素既可以是基本数据类型(如 int.long.float等)的变量,也可以是一些复合数据类型(如 arr ...

  2. 【C/C++】struct探索·extern "C"含义探索 ·C++与C的混合编程·C 语言高效编程的几招

    本文为笔者阅读<嵌入式C精华>的摘录,推荐一下,不错的书 一.C/C++语言 struct深层探索 1.自然对界 struct是一种复合数据类型,其构成元素既可以是基本数据类型(如 int ...

  3. C和C++混合编程中的extern "C" {}

    引言 在用C++的项目源码中,经常会不可避免的会看到下面的代码: 1 2 3 4 5 6 7 8 9 #ifdef __cplusplus extern "C" { #endif ...

  4. xcode 左边导航栏中,类文件后面的标记“A”,&quot;M&quot;,&quot;?&quot;……等符号的含义???

    "M" = Locally modified    "U" = Updated in repository  "A" = Locally a ...

  5. 无法解决 equal to 运算中 &quot;Chinese_PRC_CI_AS&quot; 和 &quot;SQL_Latin1_General_CP1_CI_AS&quot; 之间的排序规则冲突。

    什么是排序规则(collation) 关于SQL Server的排序规则,估计大家都不陌生,在创建数据库时我们经常要选择一种排序规则(conllation),一般我们会留意到每一种语言的排序规则都有许 ...

  6. 变化Android系统属性SystemProperties.set(&quot;sys.powerctl&quot;, &quot;shutdown&quot;)关机分析

    基本介绍: 从以前的博客中提到,我们,最后,通过关机过程变化Android关机属性(SystemProperties.java由JNI呼叫接入系统属性),当然,我们也能adb命令变化Android系统 ...

  7. #ifdef __cplusplus extern "C" { #endif 含义

    转载! 1.在好多程序中我们会遇到下面代码段 #ifdef __cplusplus         extern "C" {         #endif //c语法代码段 #if ...

  8. phpcms v9中 action=&quot;position&quot; 和action=&quot;lists&quot;有什么差别, 以及action 的属性和值

    action值的含义: lists 内容数据(文章?)列表 relation 内容相关文章 hits 内容数据点击排行榜 category 内容栏目列表 position 内容推荐位列表

  9. NYOJ 741 &quot;数学家&quot;ST

    "数学家"ST 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描写叙述 ST是个非常特别的人类,不仅喜欢做一些不同平常的事,并且对于在无聊的时候怎样打发时 ...

随机推荐

  1. 【转】C# 二进制,十进制,十六进制 互转

    //十进制转二进制 Console.WriteLine(Convert.ToString(69, 2)); //十进制转八进制 Console.WriteLine(Convert.ToString(6 ...

  2. Bzoj4899 记忆的轮廓

    B. 记忆的轮廓 题目描述 通往贤者之塔的路上,有许多的危机.我们可以把这个地形看做是一颗树,根节点编号为1,目标节点编号为n,其中1-n的简单路径上,编号依次递增,在[1,n]中,一共有n个节点.我 ...

  3. php更改wampserver的站点目录

    我都wampserver安装在f盘 F:\wamp\bin\apache\Apache2.4.4\conf文件夹下的hhtpd.conf文件ctrl+f查找DocumentRoot,第二次的位置修改即 ...

  4. Qt的widget与Button添加图片

    ui.widget->setAutoFillBackground(true); QImage image; QPalette palette; image.load("D:\\Work ...

  5. [Python3网络爬虫开发实战] 1.9.2-Scrapyd的安装

    Scrapyd是一个用于部署和运行Scrapy项目的工具,有了它,你可以将写好的Scrapy项目上传到云主机并通过API来控制它的运行. 既然是Scrapy项目部署,基本上都使用Linux主机,所以本 ...

  6. 开发基本的php框架

    github路径:https://github.com/zhengchuzhou/easyPhpFramework 一.目录结构及用途 二.相关代码: 1.入口文件(index.php): <? ...

  7. C#NumberFormatInfo类

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA0sAAAD2CAIAAACImosXAAAgAElEQVR4nOy9V3Nk13X+vTt3owPSJJ ...

  8. 【01】什么是AJAX

    什么是AJAX   AJAX(异步 JavaScript 和 XML)是 synchronous(英[ˈsɪŋkrənəs]) JavaScript and XML 的简称. AJAX不是一门新的编程 ...

  9. BFS简单迷宫

    常见迷宫: 输入迷宫 启点 终点 然后求最短路径 BFS例题 用dist[][]数组来记录 启点到每个点的最短路径 #include <iostream> #include <fst ...

  10. hdu - 1068 Girls and Boys (二分图最大独立集+拆点)

    http://acm.hdu.edu.cn/showproblem.php?pid=1068 因为没有指定性别,所以要拆点,把i拆分i和i’ 那么U=V-M (M是最大匹配,U最大独立集,V是顶点数) ...