extern C配合__cplusplus实现CPP文件和C文件的函数互相调用
2017-07-25 15:48
751 查看
C语言 c语言
C和CPP的编译后的区别
先看一下区别,首先看一下编译一个最简单的函数
demo.c
demo.cpp
demo.cpp
分别编译
$ gcc -S demo.c
$ gcc -S demo.cpp
对比一下编译出来的汇编代码
demo.c
加入了 extern “C” 的 demo.cpp
没有 extern “C” 的 demo.cpp
这里从cpp中对函数的重载处理开始说起。
在c++中,为了支持重载机制;
在编译生成的汇编码中,要对函数的名字进行一些处理,加入比如函数的返回类型等等.
而在C中,
只是简单的函数名字而已,不会加入其他的信息.
也就是说:C++和C对产生的函数名字的处理是不一样的
主要区别在于原本的函数名 testFunction 在C文件中保留了原来的名字;
但是在CPP文件中,没有引入extern “C” 编译后名字变更了
testFunction >>>> _Z12testFunctionv
现实中遇到CPP文件中的某一个函数去调用之前用C文件编写和编译好的函数,会出现:
CPP里的函数会根据C++的规则给函数名字加上前缀后缀之后,使用 _Z12testFunctionv 去查找函数的实现
就会出现查找不到函数名的链接异常, 直接就提示了函数未实现
我们需要告诉编译器查找函数实现时,不要使用C++的规则查找,而是使用C语言的规则
C和C++对函数的处理方式是不同的。
extern”C”是使C++能够调用C语言实现的库文件的一个手段
C++之父在设计C++之时
考虑到当时已经存在了大量的C代码 为了支持原来的C代码和已经写好C库
需要在C++中尽可能的支持C,而extern “C”就是其中的一个策略。
最规范的做法是头文件写成
__cplusplus是cpp中的自定义宏
那么定义了这个宏的话表示这是一段cpp的代码;
这样可以判断到,原本C语言实现的函数被链入CPP文件中了,该告诉编译器不要因此使用CPP的规则来处理我,而是使用C的规则
如果没有宏定义 __cplusplus , 说明我仍然是在C文件里面被调用,不需要特殊照顾。
extern”C”是为了CPP文件能够使用到C文件, 在C文件中使用extern”C”是无法通过编译的
会出现 error: expected identifier or ‘(’ before string constant
只能在CPP文件和H文件中调用
参考 http://blog.csdn.net/thanklife/article/details/7362893
C文件和CPP文件中的函数互相调用
或者加入头文件的写法
使用头文件的写法,把文件的后缀互换结果不变;
在main.c中,可以把头文件的引用去掉,但是如果是main.cpp的话,把头文件去掉就编译错误;
这是因为c和c++有个比较大的区别
编译C语言时 编译器会去猜测且主动搜索当前目录或者系统环境变量下的目录的文件 并引入;
编译C++时 编译器严格要求函数声明后使用 无声明直接报错 未定义;
还有一种方法就是把文件编译成库,再调用就即可;
这样就可以在链接生成可执行文件的环节中 省去指定标准C++编译器-lstdc++
C和CPP的编译后的区别
先看一下区别,首先看一下编译一个最简单的函数
demo.c
void testFunction(){ return; }
demo.cpp
extern "C"{
void testFunction(){ return; }
}
demo.cpp
void testFunction(){ return; }
分别编译
$ gcc -S demo.c
$ gcc -S demo.cpp
对比一下编译出来的汇编代码
demo.c
加入了 extern “C” 的 demo.cpp
没有 extern “C” 的 demo.cpp
这里从cpp中对函数的重载处理开始说起。
在c++中,为了支持重载机制;
在编译生成的汇编码中,要对函数的名字进行一些处理,加入比如函数的返回类型等等.
而在C中,
只是简单的函数名字而已,不会加入其他的信息.
也就是说:C++和C对产生的函数名字的处理是不一样的
主要区别在于原本的函数名 testFunction 在C文件中保留了原来的名字;
但是在CPP文件中,没有引入extern “C” 编译后名字变更了
testFunction >>>> _Z12testFunctionv
现实中遇到CPP文件中的某一个函数去调用之前用C文件编写和编译好的函数,会出现:
CPP里的函数会根据C++的规则给函数名字加上前缀后缀之后,使用 _Z12testFunctionv 去查找函数的实现
就会出现查找不到函数名的链接异常, 直接就提示了函数未实现
我们需要告诉编译器查找函数实现时,不要使用C++的规则查找,而是使用C语言的规则
C和C++对函数的处理方式是不同的。
extern”C”是使C++能够调用C语言实现的库文件的一个手段
C++之父在设计C++之时
考虑到当时已经存在了大量的C代码 为了支持原来的C代码和已经写好C库
需要在C++中尽可能的支持C,而extern “C”就是其中的一个策略。
最规范的做法是头文件写成
#ifdef __cplusplus extern "C" { #endif void testFunction(); #ifdef __cplusplus } #endif
__cplusplus是cpp中的自定义宏
那么定义了这个宏的话表示这是一段cpp的代码;
这样可以判断到,原本C语言实现的函数被链入CPP文件中了,该告诉编译器不要因此使用CPP的规则来处理我,而是使用C的规则
如果没有宏定义 __cplusplus , 说明我仍然是在C文件里面被调用,不需要特殊照顾。
extern”C”是为了CPP文件能够使用到C文件, 在C文件中使用extern”C”是无法通过编译的
会出现 error: expected identifier or ‘(’ before string constant
只能在CPP文件和H文件中调用
参考 http://blog.csdn.net/thanklife/article/details/7362893
C文件和CPP文件中的函数互相调用
// function.cpp #include <stdio.h> extern "C" void PrintHello(); void PrintHello(){ printf("I am %s\n", __FILE__); }
// main.c #include <stdio.h> extern void PrintHello(); int main(){ printf("I am %s\n", __FILE__); PrintHello(); return 0; }
$ gcc g++ -c function.cpp $ gcc -c main.c $ gcc main.o function.o -lstdc++ -o test $ ./test I am main.c I am function.cpp
或者加入头文件的写法
// function.h #ifndef _FUNCTION_H_ #define _FUNCTION_H_ #ifdef __cplusplus extern "C" { #endif void PrintHello(); #ifdef __cplusplus } #endif #endif
// function.cpp #include <stdio.h> #include "function.h" void PrintHello(){ printf("I am %s\n", __FILE__); }
// main.c #include <stdio.h> #include "function.h" int main(){ printf("I am %s\n", __FILE__); PrintHello(); return 0; }
使用头文件的写法,把文件的后缀互换结果不变;
在main.c中,可以把头文件的引用去掉,但是如果是main.cpp的话,把头文件去掉就编译错误;
这是因为c和c++有个比较大的区别
编译C语言时 编译器会去猜测且主动搜索当前目录或者系统环境变量下的目录的文件 并引入;
编译C++时 编译器严格要求函数声明后使用 无声明直接报错 未定义;
还有一种方法就是把文件编译成库,再调用就即可;
这样就可以在链接生成可执行文件的环节中 省去指定标准C++编译器-lstdc++
$ gcc -c function.c -o function.o $ ar rcs libfunction.a function.o $ g++ main.cpp -L./ -lfunction -o test $ chmod 777 test $ ./test I am main.c I am function.cpp
相关文章推荐
- C++ 保存在两个cpp文件中函数,怎样声明才能互相调用?
- C++ 文件里面调用C文件里面的函数——extern "C" 用法解析
- 实现一个so库文件名称为libupper.so提供给c/cpp调用
- 语法分析表产生器的代码之三:自定义类的实现函数文件implement_syntax.cpp
- 同一个C语言工程不同C文件之间的函数互相调用问题(一)
- MATLAB调用C文件再在C文件中调用MATLAB函数(即mex文件中调用matlab函数)
- C/C++文件中函数互相调用
- 关于Qt 两个.cpp文件相互调用各自的函数
- 不要用从C文件中的入口去调用CPP文件中的函数
- cpp文件调用CUDA .cu文件实现显卡加速相关编程
- 函数声明放在头文件中,函数的定义放在实现文件中,然后在主函数中调用
- 2.6版本Linux上替换系统调用函数实现隐藏文件学习
- 实现一个so库文件名称为libupper.so提供给c/cpp调用
- 同一个C语言工程不同C文件之间的函数互相调用问题(二)
- 如何在cpp文件中调用gcc编译的.o文件的函数
- cpp文件调用CUDA .cu文件实现显卡加速相关编程
- extern实现源文件(头文件)之间变量和函数的引用
- 在.h文件中写声明,在.cpp文件中写变量和函数,以及实现类的函数
- 头文件里面实现一个函数,在两个cpp中包含,则重复定义,如果加上inline则不会报错
- C语言学习4: 函数返回值与传入参数,关于函数值传递和类型隐性转换,变量不同的作用域,static变量,多文件编译例如两个C文件,显示函数调用语句跳转,递归,斐波那契数列,多文件编译相同变量的问题。