Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1466934
  • 博文数量: 596
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 173
  • 用 户 组: 普通用户
  • 注册时间: 2016-07-06 15:50
个人简介

在线笔记

文章分类

全部博文(596)

文章存档

2016年(1)

2015年(104)

2014年(228)

2013年(226)

2012年(26)

2011年(11)

分类: C/C++

2013-03-15 23:06:01

一、 基础知识

函数调用,编译器只要知道函数的参数类型和返回值以及函数名就可以进行编译连接。那么为了让C调用C++接口或者

是说C++调用C接口,就必须是调用者和被调用者有着同样的编译方式。这既是extern "C"的作用,

extern C”是的程序按照C的方式编译。

 

//cplus.cpp 

//按照C++方式编译程序 

int Operation(int){}

 

$g++ -c cplus.cpp -o cplus.o

$nm cplus.o

00000000 T _Z9Operationi

 

//C++

extern "C" 

int Operation(int) {}

$g++ -c cplus.cpp -o cplus.o

$nm cplus.o

00000000 T Operation

 

提供给C的接口必须加 extern "C"。这里还只是确定了编译方式,extern "C"只能让编译器安C的方式编译。但是C并不认识

extern "C",这里还要加一道工序:

C文件中 extern下接口。

extern int Operation(int)

这样C程序就认识接口函数了。下面以一个简单的例子来说明具体如何让封装C++接口给C使用。

  

$ gcc -o cpp2c cpp2c.o csayhello.o -lstdc++    (gcc,链接的时候要指定 C++ 标准库)

$ g++ -o cpp2c cpp2c.o csayhello.o          (g++C++ 标准库默认会被链接。)

或者

$ gcc cpp2c.cpp csayhello.c -lstdc++

 

 

1.先看代码

//add.c,还是正常的C代码,没有一丝不同

#include

 

 

int add(int m, int n)

{

    return m + n;

}

 

void _cout(int m)

{

    printf("result = %d\n", m);

}

 

$ gcc -c add.c

$ nm add.o

0000000e T _cout

00000000 T add

         U printf

可以看出

int add(int m, int n); ==> U add

void _cout(int m);  ==> U _cout

 

2.再看代码

//main.cpp

#include

 

//没有加extern "C"

int add(int m, int n);

void _cout(int m);

 

int main(int argc, char **argv)

{

    _cout(add(1,1));

    return 0;

}

$ g++ -c main.cpp

$ nm main.o

0000000e T _cout

00000000 T add

         U printf

 

0000006c t _GLOBAL__I_main

         U _Z3addii

0000002c t _Z41__static_initialization_and_destruction_0ii

         U _Z5_couti

         U _ZNSt8ios_base4InitC1Ev

         U _ZNSt8ios_base4InitD1Ev

00000000 b _ZStL8__ioinit

         U __cxa_atexit

         U __dso_handle

         U __gxx_personality_v0

00000000 T main

 

可以看出

int add(int m, int n); ==> U _Z3addii

void _cout(int m);  ==> U _Z5_couti

 

3.加了extern "C",再看代码

#include

 

extern "C" {

 

int add(int m, int n);

void _cout(int m);

 

};

 

int main(int argc, char **argv)

{

    _cout(add(1,1));

    return 0;

}

 

$ g++ -c main.cpp

$ nm main.o

0000006c t _GLOBAL__I_main

0000002c t _Z41__static_initialization_and_destruction_0ii

         U _ZNSt8ios_base4InitC1Ev

         U _ZNSt8ios_base4InitD1Ev

00000000 b _ZStL8__ioinit

         U __cxa_atexit

         U __dso_handle

         U __gxx_personality_v0

         U _cout

         U add

00000000 T main

可以看出,extern "C"

int add(int m, int n); ==> U add

void _cout(int m);  ==> U add

 

4.关键来了!!!

对比,没有加extern "C"

int add(int m, int n); ==> U _Z3addii

void _cout(int m);  ==> U _Z5_couti

 

可以得出结论,extern "C"能让G++编译器按C的方式编译。

 

 

 

5.更好的方法是建一个add.h的头文件,里面包含要引用的C函数,完整代码

//add.h

#ifndef ADD_H_

#define ADD_H_

 

extern "C" {

 

int add(int m, int n);

void _cout(int m);

 

};

 

#endif

 

//add.c

#include

 

 

int add(int m, int n)

{

    return m + n;

}

 

void _cout(int m)

{

    printf("result = %d\n", m);

}

 

 

//main.cpp

#include

#include "add.h"

 

int main(int argc, char **argv)

{

    _cout(add(1,1));

    return 0;

}

 

6.不小心用GCC编译了add.h,问题来了

$ gcc add.c add.h

add.h:4: error: expected identifier or ‘(’ before string constant

 

额,extern "C" C++发明的,只有G++可以编译,GCC就不能编译了。。

 

没事,找个方法让GCC编译时,没有extern "C",话说G++编译是有一个默认的宏__cplusplus。看清楚,不是__cpluscplus

说到这,你懂?

不懂看代码

//add.h,带了个套的C函数声明

#ifndef ADD_H_

#define ADD_H_

 

#ifdef __cplusplus

extern "C" {

#endif

 

int add(int m, int n);

void _cout(int m);

 

#ifdef __cplusplus

};

#endif

 

#endif

 

//add.c,还是正常的C代码,没有一丝不同

#include

 

 

int add(int m, int n)

{

    return m + n;

}

 

void _cout(int m)

{

    printf("result = %d\n", m);

}

 

 

//main.cpp,引用了带了套的C函数声明

#include

#include "add.h"

 

int main(int argc, char **argv)

{

    _cout(add(1,1));

    return 0;

}

 

7.C++调用C结束。

阅读(2338) | 评论(0) | 转发(0) |
0

上一篇:C调用C++开战咯

下一篇:LINUX加载共享库

给主人留下些什么吧!~~