首页 > 代码库 > c++,extern “c”
c++,extern “c”
C++中extern "C"的设立动机是实现C++与C及其它语言的混合编程。
C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不同。
例如,假设某个函数的原型为:void foo( int x, int y );该函数被C编译器编译后在符号库中的名字为_foo,
而C++编译器则会产生像_foo_int_int之类的名字(不同的编译器可能生成的名字不同,但是都采用了相同的机制,生成的新名字称为“mangled name”)。
1.如果要在C++程序中调用C语言写的函数, 在C++程序里边用 extern "C" 修饰要被调用的这个C程序,告诉C++编译器此函数是C语言写的,是C语言编译器生成的,调用他的时候请按照C语言习惯传递参数等。例子如下:
首先我们有C语言制作的函数库:libmyclib.a (参考gcc生成静态库和动态库)[1]
gcc -c clib_hello.c clib_math.c
ar -r libmyclib.a *.o
//clib_hello.c#include <stdio.h>void sayHello(void){ printf("clib hello!\n");}//clib_math.cint add(int va ,int vb){ return va+vb;}//clib_hello.hextern void sayHello(void);//clib_math.hextern int add(int va ,int vb);
然后,cpp编译链接c函数库
g++ cppMain.cpp libmyclib.a -o democpp
//cppMain.cpp#include <iostream>using namespace std;#if 0 extern "C"{////可以,但不推荐。 《华为技术有限公司c语言编程规范》 规则1.8 禁止在extern "C"中包含头文件。 #include "clib_hello.h" #include "clib_math.h"}#endifextern "C" void sayHello(void);extern "C" int add(int va ,int vb);//extern void sayHello(void);//extern int add(int va ,int vb);//编译错误,undefined reference to `xxx()‘int main(){ int i = add(2,3); cout<<"2+3="<<i<<endl; sayHello(); return 0;}
为什么标准头文件都有类似以下的结构?
#ifdef __cplusplusextern "C" {#endif//....头文件主体部分void cfree();int malloc_trim();//....#ifdef __cplusplus}; /* end of extern "C" */#endif
这样的结构保证了该头文件可以被cpp或者c程序使用,
如果#ifdef __cplusplus, 头文件主体成为extern "C"{......},保证可被cpp使用。
如果#ifndef __cplusplus, 头文件主体为 ...... ,保证可被c使用。
也有这样的方法:
#ifdef __cplusplus#define CPP_ASMLINKAGE extern "C"#else#define CPP_ASMLINKAGE#endif#define asmlinkage CPP_ASMLINKAGE....asmlinkage void resume(void);asmlinkage void free(void);....
参考:
1. gcc生成静态库和动态库 http://blog.chinaunix.net/uid-17267213-id-3057974.html
2. extern "C"的用法解析 http://www.cnblogs.com/rollenholt/archive/2012/03/20/2409046.html
3.C中如何调用C++函数 http://www.cppblog.com/franksunny/archive/2007/11/29/37510.html
c++,extern “c”