abserver 2018-07-19
由于C和C++代码在编译时生成的符号不同,而我们经常会在C代码里调用C++的代码,
或者在C++代码里调用C的代码,下面就简单总结一下二者相互调用时的语法。
最主要的就是在C++代码里添加 extern “C”
1、首先C代码调用C++
main.c
#include<stdio.h>
int sum(int a,int b);//此时sum函数生成的符号是C规则下的符号,
int main()
{
int ret=0;
ret = sum(1,2);
printf("%d",ret);
return 0;
}
test.cpp
extern "C"
{
int sum(int a, int b)//此时CPP文件函数在extern “C”里,CPP文件不再按CPP规则生成符号,
{ //而是按照C规则生成符号,这样和main.c里的sum符号名相同,在链接的时候
return a+b; //能够找到test.cpp里sum的定义。如果不加extern“C”,生成的符号为C++规则下 //的符号,main.c里的sum和这里的sum符号不同,在连接时, 就找不到符号的定义,就会报链接时的错误
}
}
2、C++调用C
main.cpp
#include<iostream>
using namespace std;
extern "C" int sum(int a,int b);//告诉编译器,按C规则生成sum符号,这样才会和test.c里的sum一样
int main() //链接时才能找到符号的定义
{
int ret=0;
ret = sum(1,2);
cout<<ret<<endl;
return 0;
}
test.c
int sum(int a, int b)//C规则生成sum符号
{
return a+b;
}
由上我们可以看出extern “C”只有在C++文件才有的语法,而C文件不存在,所以处理的时候都是在C++的代码里进行处理。C++不仅能生成C++规则的符号,还能生成C规则的符号。
… 但是,但是,一般情况下,一个公司购买别的公司的软件产品,别人不会把自己辛辛苦苦写的源代码给你的,给你的只是个接口,一般情况下是一个库,那这个时候我们就看不到源代码,更用不了源代码。此时又该如何实现C和C++的相互调用呢,由以上知道源码的情况下,我们知道,C和C++相互调用时,C源码并没有发生任何改变,改变的只是C++的代码,所以,在没有源码的情况下,C++调用C和上面的情况一样。接下来我们就详细讨论一下如何在只有一个C++库的情况下,用C调用C++库
假如sum.cpp如下,实际上用户是看不见的。
intsum(int a,int b)
{
return a+b;
}
g++ -shared -fpic -o libsum.so sum.cpp 之后,我们得到一个libsum.so库。我们知道这一个库,它的源码我们是不知道的,那此时我们该如何用C调用它来实现自己的加法呢。此时我们就借助计算机世界里一句名言:计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决。我们想办法把libsum.so里的sum封装起来。如下:
mysum.cpp
int sum(int a,int b);
extern "C"
{
int mysum(int a,int b)
{
return sum(a,b);//此时调用mysum()就相当于调用sum();
}
}
那我在C里再次调用sum时,我就调用封装的mysum(),
#include<stdio.h>
int mysum(int a,int b);
int main()
{
int ret=0;
ret = mysum(10,20);
printf("%d",ret);
}
gcc -o run main.c mysum.cpp ./libsum.so生成run 大功告成。