你真的知道C语言里extern "C" 的作用吗?
经常在C语言的头文件中看到下面的代码:
#ifdef __cplusplus
extern "C" {
#endif
// all of your legacy C code here
#ifdef __cplusplus
}
#endif
这通常用于C++和C混合编程的时候,为了防止C++的编译器在编译C文件的时候出现错误;
众所周知,C++可以进行函数名重载,但是C则没有这种功能,那这和extern "C"又有什么关系呢?
先看下面这个表格,如下所示;
| 语言 | 描述 |
|---|---|
| C | 函数名可以作为唯一ID和代码段的程序建立联系 |
| C++ | 因为重载的关系,函数名符号会被破坏,从而会更加函数的参数不同而重新生成函数符号 |
未添加 extern “C”
test.h
#ifndef TEST_H
#define TEST_H
void foo1(void);
void foo2(void);
void foo3(int i);
#endif
test.c
void foo1(void){}
void foo2(void) {}
void foo3(int i){}
int main(int argc,char** argv){
foo1();
foo2();
foo3(1);
return 0;
}
编译这两个文件,生成test.o文件,通过objdump查看函数符号;
g++ -c test.c test.h
objdump -t test.o
可以看到函数符号已经被编译器修改了;

添加extern “C”
test.h
#ifndef TEST_H
#define TEST_H
#ifdef __cplusplus
extern "C" {
#endif
void foo1(void);
void foo2(void);
void foo3(int i);
#ifdef __cplusplus
}
#endif
#endif
test.c
#ifdef __cplusplus
extern "C" {
#endif
void foo1(void){}
void foo2(void) {}
void foo3(int i){}
#ifdef __cplusplus
}
#endif
int main(int argc,char** argv){
foo1();
foo2();
foo3(1);
return 0;
}
编译这两个文件,生成test.o文件,通过objdump查看函数符号;
g++ -c test.c test.h
objdump -t test.o
这时候函数符号是正确的;

extern “C” 是告诉C++的编译器不要打我这些C函数的主意;参考这篇文章会更加详细。
你真的知道C语言里extern "C" 的作用吗?的更多相关文章
- c语言里如何调用汇编里的变量?
c语言里如何调用汇编里的变量? 汇编语言:是声明全局变量 .globl _end_ofs _end_ofs: .word _end - _start c语言:声明这个变量,然后再调用这个变量 void ...
- 解决全局变量共享---C语言的extern关键字用法
在调试程序时,有一个参数需要在多个函数之间传递,因为是作为调试参数,不想将参数引入到函数中. 很自然的想到使用全局变量来表示这个公共参数,工程代码的结构如下: main.c test.c test.h ...
- c语言里用结构体和指针函数实现面向对象思想
一.基础研究 观察如下两个程序a.c和b.c: A.c: B.c: 这两个程序都是要实现在屏幕上第10行40列打印一个绿色的字符c: 这两个程序的数据组织方式是一样的,都是使用结构体,而且对共性和个性 ...
- [原创]C语言里为何会有“2+2=5”的结果
原文链接:C语言里为何会有“2+2=5”的结果 写这篇原创文章是因为看到了极客中的一篇文章<有趣各种编程语言实现2+2=5>,其中C语言是这样实现的: int main() { ″; // ...
- const分别在C和C++语言里的含义和实现机制
const的含义 简单地说:const在c语言中表示只读的变量,而在c++语言中表示常量. C语言 const是constant的缩写,是恒定不变的意思,也翻译为常量,但是很多人都认为被 ...
- C语言里全局变量管理
C语言里信息封装比較弱,仅仅有静态变量的文件作用域. 假设不加约束.非常easy造成全局变量满天飞. 假设定义一个全局结构体.把全局变量都放到这个GlobleVariate里,应该好管一些,至少比裸奔 ...
- C#里partial关键字的作用(转摘)
C#里partial关键字的作用(转摘) 1. 什么是局部类型? C# 2.0 引入了局部类型的概念.局部类型允许我们将一个类.结构或接口分成几个部分,分别实现在几个不同的.cs文件中. 局部类型适用 ...
- extern "C"的作用
一.概述 在C语言的头文件中,经常可以看到如下的代码,那这个是什么作用呢? #ifdef __cplusplus extern "C" { #endif /*...*/ #ifde ...
- extern C的作用详解
extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码.加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C+ ...
随机推荐
- 疲劳驾驶打瞌睡?python保障您的驾驶安全
道路千万条,安全第一条!疲劳驾驶可谓交通事故几大罪魁祸首之一,根据美国一项研究显示,司机睡眠不足4小时,交通事故肇事几率等同于醉驾. 为了减少疲劳驾驶现象,驾驶员疲劳检测应运而生.这是一项安全技术,可 ...
- D - Leading and Trailing LightOJ - 1282
题解:求n^k的前三位和后三位. 后三位直接快速幂对1000去余就可以了.前三位可以转换成浮点数来操作,也是用快速幂,我们只保留答案的前三位,当前值大于1000.0的话就除以10,直到结果小于等于10 ...
- api_DZFPKJ & api_DZFPCX
AES加密算法的网站:http://www.ssleye.com/aes_cipher.html """ AES加密(加解密算法/工作模式/填充方式:AES/ECB/PK ...
- 【08NOIP提高组】笨小猴
笨 小 猴 来自08年NOIP提高组的第一题 1.题目描述 [题目描述] 笨小猴的词汇量很小,所以每次做英语选择题的时候都很头痛.经实验证明,用这种方法去选择选项的时候选对的几率非常大!这种方法的具体 ...
- Mysql使用终端操作数据库
使用终端操作数据库 1.如何查看有什么数据库? show databases; 2.如何选择数据库? use databasesName; 3. ...
- python爬虫实战之爬取智联职位信息和博客文章信息
1.python爬取招聘信息 简单爬取智联招聘职位信息 # !/usr/bin/env python # -*-coding:utf-8-*- """ @Author ...
- printf 参数检查 __attribute__((format(printf, 1, 2)))
With GCC, I can specify __attribute__((format(printf, 1, 2))) , telling the compiler that this funct ...
- JVM原理以及深度调优(二)
JVM内存分配 内存分配其实真正来讲是有三种的.但对于JVM来说只有两种 栈内存分配: 大家在调优的过程中会发现有个参数是-Xss 默认是1m,这个内存是栈内存分配, 在工作中会发现栈OutOfMem ...
- (转)对中级 Linux 用户非常有用的 20 个命令
也许你已经发现第一篇文章非常的有用,这篇文章是继对初级Linux用户非常有用的20个命令的一个延伸. 第一篇文章的目的是为新手准备的而这篇文章则是为了Linux的中高级用户.在这里你将学会如何进行自定 ...
- 6.Python中内存是如何管理的?
Python中内存是如何管理的? Python memory is managed by Python private heap space. All Python objects and data ...