extern"C"
1、第一种理解..................................................................................................................................................1
2、第二种理解..................................................................................................................................................7
1、第一种理解
比如说你用 C++开发了一个 DLL 库,为了能够让 C 语言也能够调用你的 DLL 输出(Export)
的函数,你需要用 extern "C"来强制编译器不要修改你的函数名。
通常,在 C 语言的头文件中经常可以看到类似下面这种形式的代码:
#ifdef __cplusplus
extern "C" {
#endif
/**** some declaration or so *****/
#ifdef __cplusplus
}
#endif /* end of __cplusplus */
那么,这种写法什么用呢?实际上,这是为了让 CPP 能够与 C 接口而采用的一种语法形式。
之所以采用这种方式,是因为两种语言之间的一些差异所导致的。由于 CPP 支持多态性,也就是
具有相同函数名的函数可以完成不同的功能,CPP 通常是通过参数区分具体调用的是哪一个函数。
在编译的时候,CPP 编译器会将参数类型和函数名连接在一起,于是在程序编译成为目标文件以后,
CPP 编译器可以直接根据目标文件中的符号名将多个目标文件连接成一个目标文件或者可执行文件。
但是在 C 语言中,由于完全没有多态性的概念,C 编译器在编译时除了会在函数名前面添加一个下
划线之外,什么也不会做(至少很多编译器都是这样干的)。由于这种的原因,当采用 CPP 与 C
混合编程的时候,就可能会出问题。假设在某一个头文件中定义了这样一个函数:
int foo(int a, int b);
而这个函数的实现位于一个.c 文件中,同时,在.cpp 文件中调用了这个函数。那么,当 CPP
编译器编译这个函数的时候,就有可能会把这个函数名改成_fooii,这里的 ii 表示函数的第一参数
和第二参数都是整型。而 C 编译器却有可能将这个函数名编译成_foo。也就是说,在 CPP 编译器
得到的目标文件中,foo()函数是由_fooii 符号来引用的,而在 C 编译器生成的目标文件中,foo()
函数是由_foo 指代的。但连接器工作的时候,它可不管上层采用的是什么语言,它只认目标文件
中的符号。于是,连接器将会发现在.cpp 中调用了 foo()函数,但是在其它的目标文件中却找不到
_fooii 这个符号,于是提示连接过程出错。extern "C" {}这种语法形式就是用来解决这个问题的。
本文将以示例对这个问题进行说明。
首先假设有下面这样三个文件:
/* &le: test_extern_c.h */
#ifndef __TEST_EXTERN_C_H__
#de&ne __TEST_EXTERN_C_H__
评论3