码工声明:本人也在学习,下面有些话是网上摘抄的---吐血的CSDN,图片不支持拷贝,不支持拷贝为啥还要正常显示,导致很多贴图都没有了
只介绍c调用c++过程中我所遇到的一些低级错误
1.先介绍一下c和c++编译
如果是已经用c++编译器编译好的so文件,使用c语言直接引用是会报错的,原因是c和c++的编译器在处理函数名称时规则不同,相同的函数比如hello(int i),c语言可能会处理成hello或者_hello,具体估计与编译器有关,但c++的话由于存在重载功能,会将参数类型等信息全部包含进去,一遍唯一定位某一函数,所以c++可能命名为_Z10helloP9int,这样即使存在hello函数名称相同的,但由于参数部分的名字不同,也可以唯一定位到需要的函数。呵呵,c++我不懂,班门弄斧了,啰嗦了一句。
hello.cpp编译生成libhello.so
相同的函数下面是用c++编译的结果
“图片被CSDN吃了”
下面是通过extern "C" 选项编译的,代码如图所示
“图片被CSDN吃了”
hello.h代码
“图片被CSDN吃了”
同样hello.h中的声明也要用extern "C",否则会报错,错误如下,应该是相同函数定义规则不同冲突了
“图片被CSDN吃了”
编译过后的nm查看函数名如下
“图片被CSDN吃了”
可以看出函数hello与代码名称相同,且不带参数
2、extern "C",注意c一定要大写,小写会报错;__cplusplus 前面是两个下划线
“"C"表示的是一种链接约定,只是因C和C++语言之间的密切关系而在它们之间更多的应用而已。实际上Fortran和汇编语言也常常使用,因为它们也正好符合C实现的约定。
extern "C"指令描述的是一种链接约定,它并不影响调用函数的定义,即时做了该声明,对函数类型的检查和参数转换仍要遵循C++的标准,而不是C”
此外还有extern "FORTRAN"
还是以hello word为例,假设用cpp且不加extern "C"来编译,那么生成的libhello.so是按照c++的约定进行编译的,如果c要调用则必须使用一个中间的过度,使得编译生成的函数按照c语言的约定编译,这样在调用时才能找到
中间文件定义为helloInf.cpp,不截图了,手敲吧
#include "hello.h"
#ifdef __cplusplus
extern "C" {
#endif
void helloInf()
{
hello(1);
}
#ifdef __cplusplus
}
#endif
同理如果helloInf.h里面的声明也要加上#ifdef __cplusplus.....
编译生成的libhelloInf.so,用main.c就可以直接调用了
main.c
#include "helloInf"
void main(void)
{
helloInf();
}