你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

C语言里extern "C" 的作用

[复制链接]
gaosmile 发布时间:2020-8-24 21:38
经常在C语言的头文件中看到下面的代码:5 E2 h9 a( b1 G! D2 {& ^
#ifdef __cplusplus% y0 w4 u; T. f9 H6 h6 G
extern "C" {5 h( {* x) L3 [
#endif7 G) j  |: A! D. L% J9 q
; s2 A7 S/ h! p5 s
// all of your legacy C code here
) _$ L0 j' b! X& V% [# `0 K3 y
4 P+ @) A  k4 c# ~( B. a#ifdef __cplusplus, d# E- g$ Z( ^1 u1 M# t
}+ V. a; R3 ^. O: [6 x
#endif7 H6 h8 p# }/ [' p  a
这通常用于C++和C混合编程的时候,为了防止C++的编译器在编译C文件的时候出现错误;
' o) Y1 h3 y  B8 B& l$ i2 x" u8 F0 S众所周知,C++可以进行函数名重载,但是C则没有这种功能,那这和extern "C"又有什么关系呢?
7 B1 d: O" }- S0 n先看下面这个表格,如下所示;
[td]
语言
描述
C函数名可以作为唯一ID和代码段的程序建立联系
C++因为重载的关系,函数名符号会被破坏,从而会根据函数的参数不同而重新生成函数符号
未添加 extern "C"
test.h
#ifndef TEST_H
. D; ?; W' K; C#define TEST_H
+ C$ @! m. I! D" m, g( C
7 J1 _  z4 U7 G$ \) Rvoid foo1(void);
% y, t! k& C- L" S! i" H7 ~$ e( ^2 R4 zvoid foo2(void);' e, ]7 Q" V, a7 L
void foo3(int i);0 S5 p$ Z4 C) K
. m* a& w$ K2 S9 e! g* y
#endif
/ ~) S4 D* [: F. Q  F! ~
test.c

4 ]" q; l( N- D( nvoid foo1(void){}
3 a, R! {  r  q! {. u) ^* nvoid foo2(void) {}' s; U) r5 x% O2 ]. g8 V2 i
void foo3(int i){}4 C$ y3 h6 ?( v  T8 l# ?
5 L% Q7 t0 n* p
int main(int argc,char** argv){! q5 h1 Z7 q3 N% \/ H

/ y/ i) i% q- l* }9 V foo1();3 `" n! W; W0 K" c, p6 P, |" |
foo2();
  |6 g: w/ S* g8 B' ~% ^ foo3(1); : J/ t( f2 W! Y
return 0;
/ J. p' I8 B9 c2 @}6 k* p8 o# k( N% k5 i
( C# O5 J& w* m9 c6 e# K& I3 N4 N3 x
编译这两个文件,生成test.o文件,通过objdump查看函数符号;
g++ -c test.c test.h5 N6 q) ~, ~/ Y/ s6 i; s2 T
objdump -t test.o! R( U0 D, ]" ]& |9 B
可以看到函数符号已经被编译器修改了;
微信图片_20200824213328.png 添加extern "C"
test.h
#ifndef TEST_H
* H% b) z2 y4 i+ B3 F/ E. B#define TEST_H* `5 ]4 _5 g) `1 m+ N' O
! D, f; ?$ Z% w4 G0 H7 P9 x  e# N
#ifdef __cplusplus. o( ]- s3 P1 b% b1 \
extern "C" {
+ f! }/ `3 P/ k) o& j: k#endif! M: K0 m  t, C
void foo1(void);
0 k' O: Q! B1 \2 G* q- `# `) g* Jvoid foo2(void);
6 L1 H3 g4 K; |( }void foo3(int i);% u$ b6 r- m( c% d. S' d* D3 ~

- L. {; ^7 }' k" u#ifdef __cplusplus  G5 S4 V3 Z1 ~* w. K0 v! }5 O. }
}
+ t1 x$ i( q6 a& O#endif
/ _& r1 R8 ]: t2 ]. r+ h+ }
1 W& p" |4 e( L# J- v. `" N#endif
# p; `- P- a; ]- d
test.c
#ifdef __cplusplus
" i% s4 a2 Y+ ]* B4 B  q+ Mextern "C" {
% m' }2 C6 O' c#endif
; V/ o' ]* `5 c  r0 bvoid foo1(void){}' v  c& d* l3 ?
void foo2(void) {}1 G) w. A; l6 F0 D) k& N5 D
void foo3(int i){}
) Q+ y- F% O( J5 w4 u#ifdef __cplusplus
6 ]! O( G9 o. d}8 i! i0 Y* ^/ L) v8 i1 o) _
#endif
( |; r! k. p8 s( }& g% [1 U) \' O9 C4 X
int main(int argc,char** argv){6 g# p7 H  Q6 f8 k" q
* }* B. A9 D& C
foo1();' `  e6 Q7 @$ H5 t
foo2();
" M3 I% Q! _* B2 j+ l foo3(1);
: u7 U, \  s* Q: E& Y/ e5 g return 0;" o% C. J+ v* j# ?8 k' j- M8 e
}5 r( G$ p2 I( ?1 \

& C. M, j9 }. a" M2 C. C; j; f0 z
编译这两个文件,生成test.o文件,通过objdump查看函数符号;
g++ -c test.c test.h6 g1 O# H2 I: K
objdump -t test.o4 z" Z. @. m8 o* i% n% Q9 O
这时候函数符号是正确的;
微信图片_20200824213331.png
extern "C" 是告诉C++的编译器不要打我这些C函数的主意。
% c6 i; s/ |/ m8 O& Z8 N- X

4 D5 x* O( E  O. J+ V
赞 收藏 3 评论0 发布时间:2020-8-24 21:38

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版