|
经常在C语言的头文件中看到下面的代码:5 E2 h9 a( b1 G! D2 {& ^ #ifdef __cplusplus% y0 w4 u; T. f9 H6 h6 Gextern "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 #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文件的时候出现错误; [td]众所周知,C++可以进行函数名重载,但是C则没有这种功能,那这和extern "C"又有什么关系呢? 先看下面这个表格,如下所示;
test.h #ifndef TEST_H#define TEST_H void foo1(void); void 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 test.c void foo1(void){} void 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 foo1();3 `" n! W; W0 K" c, p6 P, |" | foo2(); foo3(1); : J/ t( f2 W! Y return 0; }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 Tobjdump -t test.o! R( U0 D, ]" ]& |9 B 可以看到函数符号已经被编译器修改了;
test.h #ifndef TEST_H#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" { #endif! M: K0 m t, C void foo1(void); void foo2(void); void foo3(int i);% u$ b6 r- m( c% d. S' d* D3 ~ #ifdef __cplusplus G5 S4 V3 Z1 ~* w. K0 v! }5 O. } } #endif #endif test.c #ifdef __cplusplusextern "C" { #endif void foo1(void){}' v c& d* l3 ? void foo2(void) {}1 G) w. A; l6 F0 D) k& N5 D void foo3(int i){} #ifdef __cplusplus }8 i! i0 Y* ^/ L) v8 i1 o) _ #endif & 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(); foo3(1); return 0;" o% C. J+ v* j# ?8 k' j- M8 e }5 r( G$ p2 I( ?1 \ 编译这两个文件,生成test.o文件,通过objdump查看函数符号; g++ -c test.c test.h6 g1 O# H2 I: Kobjdump -t test.o4 z" Z. @. m8 o* i% n% Q9 O 这时候函数符号是正确的;
extern "C" 是告诉C++的编译器不要打我这些C函数的主意。 % c6 i; s/ |/ m8 O& Z8 N- X |
微信公众号
手机版