extern “c” 这个是为了cpp文件能够调用由c语言生成的.o文件
c++源程序调用c库
这是因为c编译出来的.o文件的函数命名和cpp编译出来的函数命名不一样,
如下,cfile.c中
int foo(int x,int y)
{
return x+y;
}
gcc cfile.c -o cfile.o -c
执行上面命令生成cfile.o时,我们
readelf cfile.o -s
可以看到
可以看到,cfile.o编译出来的函数名为fun
存在一个chead.h文件
int foo(int,int );
还有一个文件cppfile.cpp如下:
#include"iostream"
//extern "C"
//{
#include"chead.h"
//}
using namespace std;
int main(){
cout<<foo(1,3)<<endl;
}
g++ cppfile.cpp -o cppfile.o -s
readelf cppfile.o -s
可以看到foo函数被命名_Z3fooii,其实这个也是c++函数命名规律,后面两个ii代表两个参数都为int,int。
如果接下来我们执行下面命令就会出错。
g++ cfile.o cppfile.o -o main
提示找不到foo(int,int)函数.这很好理解呀,你要找的是_Z3fooii,而c中编译出来的是foo,怎么可能找到。
这个时候,就轮到extern “c” 这个出场了。这个东西就是让在其括号中的东西按照c的命名,而不是c++的,
所以我们把上面cppfile.c中的extern “c” 部分的//去掉,再编译
可以看到foo函数被编译器按照c的命名方法命名为foo,接下来
g++ cfile.o cppfile.o -o main
就不会出错了。
c源程序调用c++库
如果有extern “c++” 这个关键字,什么问题就都解决了,但是没有,所以,我们得找另一条路径,
/*C++库源文件hello.cpp*/
#include <iostream>
void funcpp()
{
std::cout << "hello, world" << std::endl;
}
编译:g++ –shared -o libhello.so hello.cpp
中间接口库,对C++库进行二次封装
/*中间接口库 mid.cpp*/
#include <iostream>
void funcpp();
#ifdef __cplusplus
extern "C" { // 即使这是一个C++程序,下列这个函数的实现也要以C约定的风格来搞!
#endif
void m_funcpp()
{
funcpp();
}
#ifdef __cplusplus
}
#endi
g++ –shared -o libmid.so mid.cpp -lhello
这样生成的.o中,m_funcpp()函数就是用c的命名规则的,可以直接给c源程序用。