是否还需要在源文件中添加“extern C”?
c++调用c语言的函数时我们一般在c语言函数声明处用extern "C"
包c函数。例如:
///头文件 myMath.h
#ifdef __cplusplus
extern "C" {
#endif
int add(int a, int b);
#ifdef __cplusplus
}
#endif
///源文件 myMath.cpp
int add(int a, int b)
{
return a + b;
}
extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般之包括函数名。
问题来了。头文件是不会参与编译的,参与编译的是c/cpp文件。那我们是不是需要把函数定义也用extern "C"
包起来呢?显然没包起来函数没在连接的时候报错。Standard for Programming
Language C++ 184页第五段说了:
A function can be declared without a linkage specification after an explicit linkage specification has been
seen; the linkage explicitly specified in the earlier declaration is not affected by such a function declaration.
在明确的连接规范已经被声明之后,可以在没有链接规范的情况下声明函数,之前声明中明确指定的链接不受此类函数声明的影响。
也就是定义过一次之后后面的编译连接如果不声明连接规范时还是一之前声明的连接规范为准。我们平时首先是导入头文件。所以带extern "C"
的声明会早于函数定义被编译器看到,所以档编译到不带extern "C"
的函数定义时会按照头文件中的声明去编译。因此源文件中不加extern "C"
修饰也不影响。不过要是存在带extern "C"
的头文件没有被引到源文件中的场景,可能会出现还是会被按C++编译链接情况。保险起见可以在实现文件也把方法用extern "C" { }
包起来。