C++分析研究  
C++
日历
<2014年4月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910
统计
  • 随笔 - 92
  • 文章 - 4
  • 评论 - 4
  • 引用 - 0

导航

常用链接

留言簿

随笔档案

文章档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜

 

  其实在网上关于这个问题已经讨论很多了,但是大多都是重复的,确实讲解的很详细,还指出了怎么用是错误的,本来记忆就不怎么样,所以对于记忆这些错误的用法更是讨厌,还不如记忆一种通用的而且比较规范、代码阅读起来比较舒适的方法,下面我们开始吧!!!
  C、C++密不可分,平时使用更多的是C,但有时候却少不了C++,而且是C、C++混搭(混合编程)在一起的,比如,RTP视频传输,live555多媒体播放等都是C++下的,他需要调用JRTPLIB库,再比如,我那邮件发送,我也用C++写的,定义了一个Email对象,包含了成员:收发邮件地址,用户名,密码等,以及方法:邮件头、Base64编码和邮件发送这些操作,很好用,所以,很多时候,C++还是蛮不错的…但,*.c与*.cpp文件混搭在一起,不是那么的简单,.
  一、extern"C"的作用(最重点)
  1. extern "C"的真实目的是实现类C和C++的混合编程。extern "C"是由C++提供的一个连接交换指定符号,用于告诉C++这段代码是C函数。extern "C"后面的函数不使用的C++的名字修饰,而是用C.这是因为C++编译后库中函数名会变得很长,与C生成的不一致,造成C++不能直接调用C函数托福答案
  2.C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。假设某个函数的原型为:void foo(int x, int y);该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。C++提供了C连接交换指定符号extern"C"来解决名字匹配问题。
  3.被extern "C"限定的函数或变量是extern类型的;extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。被extern "C"修饰的变量和函数是按照C语言方式编译和连接的雅思答案
  4.与extern对应的关键字是static,被它修饰的全局变量和函数只能在本模块中使用。因此,一个函数或变量只可能被本模块使用时,其不可能被extern "C"修饰。
  二、extern"C"与__cplusplus
  #ifdef __cplusplus
  extern "C" {
  #endif
  #ifdef __cplusplus
  }
  #endif
  Cplusplus(C plus plus)即"C++",用于C++文档的头文件中,上面代码的意思是:如果是C++文件(*.cpp)后缀,则使用extern "C",在C++项目中应用的非常广泛。即使用gcc编译器编译,函数名为C类型如_foo.个人认为,搞懂了这两个关键字,尤其是理解extern "C"
  extern "C" 是为了C与C++混合编程而设立的关键字,假如你已经知道了关于extern "C" 的一些使用方法,想很快掌握使用策略,下面从两个角度说明:
  1)在C++程序中调用C程序,比如在CPP文件中使用C文件的某一个函数,那么可以肯定的是所使用的函数肯定是按照C语言的编译方式编译,那么仅仅通告CPP文件按照C语言调用函数的方式调用即可,而且不用再重新编译C函数,在函数所在头文件中添加extern "C"关键字,将这个头文件包含到CPP文件即可。也就是如下所示:
  #ifdef __cplusplus
  extern "C" {
  #endif
  /*… 函数声明*/
  #ifdef __cplusplus
  }
  #endif
  稍微举例说明一下:
  ?
  // cheader.h
  #ifndef _C_HEADER_
  #define _C_HEADER_
  #ifdef __cplusplus
  extern "C" {
  #endif
  #include <STDIO.H>
  #include <STDLIB.H>
  int add(int a,int b);
  #ifdef __cplusplus
  }
  #endif
  #endif
  // cfunc.c
  //#include "header.h"
  int add(int a,int b)
  {
  return a+b;
  }
  //main.cpp
  #include <IOSTREAM>
  #include "header.h"
  using namespace std;
  int main()
  {
  int a,b=0;
  b= add(2,3);
  cout《B《ENDL; pre < } 0; return><BR>
  由于。c文件中的函数就是按照C语言编译方式进行编译的,所以不包括头文件也是可以的,但是在头文件声明的时候必须进行说明,因为在CPP文件中包括的这个头文件会按照C语言的方式查找函数,不然就会按照C++的方式查找函数add<BR>
  <P><STRONG>2)在C程序中使用CPP编译的函数,这样需要重新编译函数库,在函数声明的头文件中也是如上声明,然后再函数所在的CPP文件添加上述头文件,直接编译即可,这个时候虽说在CPP文件编译,但是是安装C语言的方式编译,在C文件中同样添加上述头文件即可。</STRONG></P>
  <P><STRONG>稍微举例说明一下:</STRONG></P>
  <P><STRONG></STRONG></P>
  <PRE class=brush:java;>// cheader.h头文件
  #ifndef _C_HEADER_
  #define _C_HEADER_
  #ifdef __cplusplus
  extern "C" {
  #endif
  #include <STDIO.H>
  #include <STDLIB.H>
  int sub(int a,int b);
  #ifdef __cplusplus
  }
  #endif
  #endif
  //cppsub.cpp
  #include "header.h"
  int sub(int a,int b)
  {
  return a-b;
  }
  /*但是如果将头文件的那一行注释掉,也会在连接时出错,因为在头文件中已经说明使用C语言的方式编译,但是不说明这一点,会使用C++编译方式进行
  如果不想使用头文件,那么可以将int sub(int a,int b) 换为 extern "C" int sub(int a,int b) ,但是extern "C"在。c文件时不可以出现*/
  //cmain.c
  #include "header.h"
  int main()
  {
  int a=0,b=0;
  b = sub(2,3);
  printf("b is %d\r\n",a,b);
  return 0;
  }
  </PRE>
  但是在使用的时候也是有一定的规范的:<BR>
  //C++头文件 cppExample.h<BR>
  #ifndef CPP_EXAMPLE_H<BR>
  #define CPP_EXAMPLE_H<BR>
  extern "C" int add( int x, int y );<BR>
  #endif
  <BR>
  //C++实现文件 cppExample.cpp<BR>
  #include "cppExample.h"<BR>
  int add( int x, int y )<BR>
  {<BR>
  return x + y;<BR>
  }
  <BR>
  /* C实现文件 cFile.c<BR>
  /* 这样会编译出错:#include "cExample.h" */<BR>
  extern int add( int x, int y );<BR>
  int main( int argc, char* argv[] )<BR>
  {<BR>
  add( 2, 3 ); <BR>
  return 0;<BR>
  }
  note: 如果 cppEample.h 改成:
  #ifndef CPP_EXAMPLE_H<BR>
  #define CPP_EXAMPLE_H
  #ifdef __cplusplus
  extern "C" {
  #endif
  <BR>
  int add( int x, int y );
  #ifdef __cplusplus
  }
  #endif
  <BR>
  #endif
  则在 C 文件中 #include "cExample.h" 就不会报错了。
  总之, 无论写 c 还是 c++头文件,只要是想以后混合编程,就最好加上
  #ifdef __cplusplus
  extern "C" {
  #endif
  /**** some declaration or so *****/
  #ifdef __cplusplus
  }
  #endif /* end of __cplusplus */<BR>
  错误的原因在于在C语言中没有关键字 extern "C"<BR>
  (PS:有的人会单独使用extern "C" 来修饰某个函数,我觉得不是很好看,特别是在头文件中不能这么使用,因为在C文件中不能出现这样的关键字,所以最好使用最后介绍的条件编译 在一定条件下才使用 extern "C")<BR>
  <P></P>
  <PRE class=brush:java;><PRE class=brush:java;></PRE>
  <PRE class=brush:java;></PRE>
  <PRE class=brush:java;></PRE>
  <PRE class=brush:java;></PRE>
  <PRE class=brush:java;></PRE>
  <PRE class=brush:java;></PRE>
  <PRE class=brush:java;></PRE>
  <PRE class=brush:java;></PRE>
  <PRE class=brush:java;></PRE>
  <PRE class=brush:java;></PRE> </PRE>

posted on 2014-04-26 13:45 HAOSOLA 阅读(514) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


 
Copyright © HAOSOLA Powered by: 博客园 模板提供:沪江博客
PK10开奖 PK10开奖