C++和C相互调用实际工程中C++和C代码相互调用是不可避免的C++编译器能够兼容C语言的编译方式C++编译器会优先使用C++编译的方式extern关键字能强制让C++编译器进行C方式的编译
extern "C"{ // do C-style compilation here}
假设在C++中调用用C语言编写的库,如何来做?举个简单的小例子:
add.h
int add(int a, int b);
-----------------------------------
add.c#include "add.h"int add(int a,int b){ return a + b;}
gcc -c add.c -o add.o将会生成一个add.o的文件
-------------------------------------
main.cpp#include <stdio.h>#include "add.h"
int main(){ int c = add(1,3); printf("c = %d\n",c);}编译:g++ main.cpp add.o编译出错:undefined reference to 'add(int ,int )'利用nm命令查看add.o中是否有add函数nm add.o,查看发现里面已经有了add函数。那么这个地方为什么提示没有呢
因为add.o是用C语言编译器进行编译的,而main.cpp是C++代码,它想调用C的代码,而C的代码已经被编译成目标文件了。此处需要强制让C++编译器使用C语言的编译器。main.cpp#include <stdio.h>extern "C"{#include "add.h"}
int main(){ int c = add(1,3); printf("c = %d\n",c);}
-----------------------------------------------------------------------------------------
如何保证一段C代码只会以C的方式被编译?利用extern "C"不就可以了吗?注意:extern "C"是C++中才有的,C语言中不支持extern "C"这样的写法。现在要保证的是一段C代码只会以C的方式被编译,不管是C++编译器还是C语言编译器。
你可能还是会说,我就用extern "C"。当采用C语言编译器编译带有extern "C"的语句时,是编译不过的。解决方案:__cplusplus是C++编译器内置的标准宏定义__cplusplus的意义确保C代码以统一的C方式被编译成目标文件#ifdef __cplusplusextern "C" {#endif
//C-Style Complitation
#ifdef __cplusplus}#endif--------------------------------------
main.c
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "add.h"
#ifdef __cplusplus
}
#endif
int main()
{
int c = add(1,2);
printf("c=%d\n",c);
return 0;
}
这样用C语言编译器就通过了同样利用C++编译器也能编译过。
注意事项:C++编译器不能以C的方式编译重载函数编译方式决定函数名被编译后的目标名-C++编译方式将函数名和参数列表编译成目标名 (可以编译完成后,用nm命令查看)-C编译方式只将函数名作为目标名进行编译
小结:函数重载是C++对C的一个重要升级函数重载通过函数参数列表区分不同的同名函数extern关键字能够实现C和C++的相互调用。(extern代码块中,不能有重载函数)编译方式决定符号表中的函数名的最终目标名。
本质上是不允许函数名相同的,只不过C++编译器在编译的时候,将参数作为了函数名的一部分。这就是为什么函数名相同还能编译过的地方。而C语言就不行(它在编译的时候,函数名就是函数名,没有参数列表,因此就无法区分同名函数了,因此就没有重载的概念了),这就是因为编译方式的不同,导致的结果