转载:https://light-city.club/sc/basic_content/extern/#extern-c

1.C++与C编译区别

在C++中常在头文件见到extern "C"修饰函数,那有什么作用呢? 是用于C++链接在C语言模块中定义的函数。

C++虽然兼容C,但C++文件中函数编译后生成的符号与C语言生成的不同。因为C++支持函数重载,C++函数编译后生成的符号带有函数参数类型的信息,而C则没有。

例如int add(int a, int b)函数经过C++编译器生成.o文件后,add会变成形如add_int_int之类的, 而C的话则会是形如_add, 就是说:相同的函数,在C和C++中,编译后生成的符号不同。

这就导致一个问题:如果C++中使用C语言实现的函数,在编译链接的时候,会出错,提示找不到对应的符号。此时extern "C"就起作用了:告诉链接器去寻找_add这类的C语言符号,而不是经过C++修饰的符号。

2.C++调用C函数

C++调用C函数的例子: 引用C的头文件时,需要加extern "C"

//add.h
#ifndef ADD_H
#define ADD_H
int add(int x,int y);
#endif//add.c
#include "add.h"int add(int x,int y) {return x+y;
}//add.cpp
#include <iostream>
#include "add.h"
using namespace std;
int main() {add(2,3);return 0;
}

编译:

//Generate add.o file
gcc -c add.c

链接:

g++ add.cpp add.o -o main

没有添加extern "C" 报错:

> g++ add.cpp add.o -o main
add.o:在函数‘main’中:
add.cpp:(.text+0x0): `main'被多次定义
/tmp/ccH65yQF.o:add.cpp:(.text+0x0):第一次在此定义
/tmp/ccH65yQF.o:在函数‘main’中:
add.cpp:(.text+0xf):对‘add(int, int)’未定义的引用
add.o:在函数‘main’中:
add.cpp:(.text+0xf):对‘add(int, int)’未定义的引用
collect2: error: ld returned 1 exit status

添加extern "C"后:

add.cpp

#include <iostream>
using namespace std;
extern "C" {#include "add.h"
}
int main() {add(2,3);return 0;
}

编译的时候一定要注意,先通过gcc生成中间文件add.o。

gcc -c add.c

然后编译:

g++ add.cpp add.o -o main

上述案例源代码见:

  • add.h

  • add.c

  • add.cpp

2.C中调用C++函数

extern "C"在C中是语法错误,需要放在C++头文件中。

// add.h
#ifndef ADD_H
#define ADD_H
extern "C" {int add(int x,int y);
}
#endif// add.cpp
#include "add.h"int add(int x,int y) {return x+y;
}// add.c
extern int add(int x,int y);
int main() {add(2,3);return 0;
}

编译:

g++ -c add.cpp

链接:

gcc add.c add.o -o main

上述案例源代码见:

  • add.h

  • add.c

  • add.cpp

综上,总结出使用方法,在C语言的头文件中,对其外部函数只能指定为extern类型,C语言中不支持extern "C"声明,在.c文件中包含了extern "C"时会出现编译语法错误。所以使用extern "C"全部都放在于cpp程序相关文件或其头文件中。

总结出如下形式:

(1)C++调用C函数:

//xx.h
extern int add(...)//xx.c
int add(){}//xx.cpp
extern "C" {#include "xx.h"
}

(2)C调用C++函数

//xx.h
extern "C"{int add();
}
//xx.cpp
int add(){}
//xx.c
extern int add();

extern “C“那些事相关推荐

  1. 谈谈程序链接及分段那些事

    谈谈程序链接及分段那些事 如果读过我之前的文章就会知道,程序构建大概需要经历四个过程:预处理.编译.汇编.链接,这里主要介绍链接这一过程. 链接链的是什么? 链接链的就是目标文件,什么是目标文件?目标 ...

  2. 通过GetProcAddress函数动态调用dll中地函数,是否必须通过extern C声明导出函数?(转)...

    通过GetProcAddress函数动态调用dll中的函数,是否必须通过extern "C"声明导出函数? [已结贴,结贴人:darongtou] 如题,网上搜了N多资料,一直找不 ...

  3. 散谈游戏保护那点事~就从_TP开始入手吧

    标 题: [原创]散谈游戏保护那点事~就从_TP开始入手吧 作 者: crazyearl 时 间: 2010-12-20,02:37:22 链 接: http://bbs.pediy.com/show ...

  4. Xamarin的坑 - 绑定(二) - 高德iOS SDK(.Framework)绑定的一些事

    编者语:入门总是用一个hello world,总会让人觉得写code会是很容易的事.开篇绑定了一下微信SDK,不会有太多的难点,可是接下来的这个例子如果欠缺一些耐心,估计你整个人就崩溃了(我从来不会放 ...

  5. linux内核那些事之buddy(anti-fragment机制)(4)

    程序运行过程中,有些内存是短暂的驻留 用完一段时间之后就可以将内存释放以供后面再次使用,但是有些内存一旦申请之后,会长期使用而得不到释放.长久运行有可能造成碎片.以<professional l ...

  6. linux那些事之early pape fault

    由linux那些事之中断与异常(AMD64架构)_2>分析可知,在kernel启动过程中首先安装的early中断dt_setup_early_handler中,主要是对page fault中断支 ...

  7. 【c语言】关键字存储类型讲解(auto,extern,static,register,const)

    渣渣C的学习之路 用最简单的话,让你最快速明白! C语言中,每一个变量和函数都有2个属性:数据类型和数据的存储类别.C的存储类别有4种:自动的(auto).静态的(static).寄存器的(regis ...

  8. java api 获取jvm实例_JVMTI那些事——和Java相互调用

    前面几篇文章介绍了JVMTI接口的一些基本概念,以及如何编写一个基于JVMTI的agent. 那些简单的例子只是JVMTI agent自己实现一些简单的功能,如果能够将JVMTI提供的接口经过包装之后 ...

  9. GetProcAddress()函数动态调用DLL中的函数,是否必须通过extern C声明导出函数?

    GetProcAddress()函数动态调用DLL中的函数,是否必须通过extern C声明导出函数? 通过GetProcAddress函数动态调用dll中的函数,是否必须通过extern " ...

最新文章

  1. English Spoken Math
  2. 《自然语言处理入门》不是 NLP 学习路上的万能药
  3. mac安装mysql修改密码_Mac下安装MySQL 5.7.28并且修改root密码-Go语言中文社区
  4. python hex 补0_Python保留前导零的二进制到十六进制转换
  5. php三元运算符要多个赋值,php让三元运算符用起来更简单的小技巧
  6. mqtt android封装,Android之MQTT封装使用
  7. python 的作用
  8. iOS开发中防止键盘挡住UITextField解决方案
  9. [翻译] ASP.NET MVC Framework控制器操作安全性
  10. 使用Pixel Bender Toolkit制作特效——给过滤器增加参数(Part 3)
  11. matlab erf erfi,中国樱桃AP2/ERF转录因子在花芽休眠解除过程的表达与作用研究
  12. 如何将wav转为mp3格式,wav中间mp3步骤
  13. 立创EDA学习笔记(2)——创建元件符号
  14. python #hsv空间中Hue色度/色调在色相环上的角#冷暖色调 在色相环上的范围
  15. STM32开发入门及实战
  16. 信号截断及能量泄漏效应
  17. php.bak是什么,bak文件是什么
  18. linux全屏时钟应用下载,全屏时钟下载安装-全屏时钟app下载 苹果版v2.3-PC6苹果网...
  19. 2016里约奥运会倒计时 技术团队谈幕后科技
  20. 一文带你了解Ribbon负载均衡和Hystrix熔断器

热门文章

  1. python中的range与xrange
  2. Beanstalkd消息队列的安装与使用
  3. python基础===字符串的制表,换行基础操作
  4. 物联网将如何改善社会运行效率?
  5. 【转载】cocos2d-x类型转换(CCstring int string char UTF-8互转)以及字符串详解
  6. centos6.6-zabbix2.4.5安装实战
  7. CSDN博文大赛火爆开启
  8. [Android Memory] Android系统中查看某个应用当前流量的方法
  9. VB.NET 对于类型的传递按值或者按引用
  10. Linux 命令(一) findgrep文件查找命令