软件需求请点击此处留言菜鸟资源为你准备 立即查看

第三章:掌握在 C++中如何使用 C,了解C++程序的基本构成,快速入门指南

第三章:掌握在 C++中如何使用 C,了解C++程序的基本构成,快速入门指南

  大多数的 C++开发人员也许会遇到这样的问题:你的开发工程是C++语言实现的,但你使用的库却是标准 C语言编译器编程的库,在编译链接时,总是不停地报出错误。   为了演示我们经常遇到的问题,来看如下这段代码:   将上述代码在Visua...

当前版本

软件大小

软件语言

是否破解

  大多数的 C++开发人员也许会遇到这样的问题:你的开发工程是C++语言实现的,但你使用的库却是标准 C语言编译器编程的库,在编译链接时,总是不停地报出错误。

  为了演示我们经常遇到的问题,来看如下这段代码:

  1.   /*C 语言头文件:Max.h*/
  2.   #ifndef MAX H
  3.   #define MAX_H
  4.   //Max 函数声明,此函数功能为求得两数据 nA和 nB的大者
  5. #endif
  6. /*C 语言实现文件:Max.c*/
  7. #include "Max.h"
  8. // 求取两数的最大值
  9. int Max(int nA,int nB)
  10. {
  11.     return((nA>nB)?(nA):(nB));
  12. }
  13. // C++语言调用文件:Main.cpp
  14. #include "Max.h'
  15. int _tmain(int argc,char* argv[])
  16. {
  17.    nt nMax=Max(1,2);
  18.    return 0;
  19. }

  将上述代码在Visual C++编译器中编译,Visual C++会报出错误:

  1.   error LNK2019:无法解析的外部符号"int_cdecl Max(int,int)”(?Max@@YAHHH@Z),该符
  2. 号在函数wmain中被引用

  为了说明上述代码存在的问题,现在把上述代码修改成如下形式:

  1.     /*C语言头文件:Max.h*/
  2.     #ifndef_MAX_H
  3. _
  4.     #define_MAX_H_
  5. #ifdef _cplusplus
  6. exten"C"{
  7. #endif
  8.   int Max(int nA,int nB);
  9. #ifdef _cplusplus
  10. };
  11. #endif
  12.   #endif
  1.   /*C语言实现文件:Max.c*
  2.   #include"Max.h'
  3.   int Max(intnA,int nB)
  4.   {
  5.     retum ((nA>nB)?(nA):(nB));
  6.   }
  7.   //C++语言调用文件:Main.cpp
  8.   #include"Max.h"
  9.   int_tmain(int argc, char*argv[])
  10.   {
  11.     intnMax=Max(1,2);
  12.     return 0;
  13.   }

  在Visual C++编译器中重新编译上述代码,发现此次竟然编译通过了。C++开发新手一般都会认为是代码写错了:Max函数哪里实现或Main函数中哪里的调用方式搞错了。不知你是否注意到,Max 函数实现文件类型是*.c 而不是*.cpp。此处编译出现的 LNK2019 错误就是今天要讨论的主题。

  首先,对比上述两段代码发现,第二次的代码比第一次的代码多了如下代码段:

  1.   #ifdef _cplusplus
  2.   extern"C"{
  3.   #endif
  4.   #ifdef _cplusplus
  5.   };
  6.   #endif

  所以可得出结论:在C++中调用C的代码必须把原来的C语言声明放到extern “C”{/*code*/}中,否则在 C++中无法编译通过。

  当然,好奇心重的读者也许会产生新的问题了:为什么在C++中调用C的代码必须把原来的 C 语言声明放到 extern “C”{/*code*/}中,否则 C++无法编译通过呢?

  带着这个问题我们看一下隐藏在现象背后深层次的真实原因:C和 C++语言具有不同的编译和链接方式。C 语言编译器编译函数时不带函数的类型和作用域信息,只包含函数符号名字;而C++编译器为了实现函数的重载,在编译时会带上函数的类型和作用域信息。

  例如,假设某一函数原型为:

  1.   int Func(int nA, int nB);

  C语言编译器把函数编译成类似Func的符号,C链接器只要找到这个符号就可以连接成功,实现调用。所以可以看出,C编译器不会对函数的参数和作用域信息进行校验,只是假设这些信息都是正确的。同样这也是C语言编译器的缺点所在。

  而在强调安全的C++语言中,编译器会检查参数类型和作用域信息,上述函数原型会编译成ZFuncint int这样的符号(也正是这种机制为函数重载的实现提供了必要的支持)。在链接过程中,C++链接器会在函数原型所在模块生成的目标文件中查找Z_Func_int_int 这样的符号。

  解决上述问题是设置extern”C”语法最直接的原因和动力。extern”C”的作用是告诉 C++编译器在查找调用链接符号时采用C 语言的方式,让编译器寻找_Func 而不是查找Z Func int int。

  最后,介绍C++中调用C代码的3种具体实现方式:

  (1)修改C代码的头文件,当其被用于C++代码时,在声明中加入extern”C”。代码如下:

  1.   /*C语言头文件:Max.h*/
  2.   #ifndef_MAX_H_
  3.   #define_MAX_H_
  4.   exten"C"int Max(int nA,int nB);
  5.   #endif
  6.   /*C 语言实现文件:Max.c*/
  7.   #include"Max.h'
  8.   int Max(int nA,int nB)
  9.   {
  10.     returm ((nA>nB)?(nA):(nB));
  11.   }
  12.   // C++语言调用文件:Main.cpp
  13.   #include"Max.h'
  14.   
  15.   int _tmain(int argc, char* argy[])
  16.   {
  17.     intnMax=Max(1,2);
  18.     returm 0;
  19.   }

  (2)在C++代码中重新声明一下C 函数,在重新声明时添加extern”C”。代码如下:

  1.   /*C语言头文件:Max.h*/
  2.   #ifndef_MAX_H_
  3.   #define_MAX_H_
  4.   exterm int Max(int nA,int nB);
  5.   #endif
  6.   /*C 语言实现文件:Max.c*/
  7.   #include"Max.h'
  8.   int Max(int nA, int nB)
  9.   {  
  10.     return ((nA>nB)?(nA):(nB));
  11.   }
  12.   //C++语言调用文件:Main.cpp
  13.   #include "Max.h'
  14.   extern "C"intMax(int nA,int nB);
  15.   
  16.   int_tmain(int argc, char* argv[])
  17.   {
  18.     intnMax=Max(1,2);
  19.     return 0;
  20.   }

  (3)在包含C头文件时,添加 extern “C”。代码如下:

  1.   /*C语言头文件:Max.h*/
  2.   #ifndef_MAX_H_
  3.   #define_MAX_H_
  4.   extern int Max(int nA,int nB);
  5.   #endif
  6.   /*C语言实现文件:Max.c*/
  7.   #include "Max.h'
  8.   int Max(int nA,int nB)
  9.   {
  10.     return ((nA>nB)?(nA):(nB));
  11.   }
  12.   // C++语言调用文件:Main.cpp
  13.   extern "C"{
  14.   #include "Max.h'
  15.   }
  16.   int tmain(int argc, char* argv[])
  17.   {
  18.     intnMax=Max(1, 2);
  19.     return 0:
  20.   }

  注意:exten”C”一定要加在C++的代码文件中才能起作用。

  请谨记

  ●要想实现在 C++中使用大量的 C 程序库,再实现 C++与C语言混合编程,那么必须掌握extern “C”怎么使用,明白 extern”C”的使用方式。
  ●在 C++和 C 语言混合编程时,extem”C”一定要加在 C++文件中,否则 exten “C”不会发生作用。

第三章:掌握在 C++中如何使用 C,了解C++程序的基本构成,快速入门指南
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

常见问题

  • 如何安装和激活?

    每款软件会附带有安装教程,您打开安装包一目了然

  • 程序是否已损坏?文件损坏?还是其他错误?

    有错误问题,请您参考:https://www.xxx.com/error

  • 如何更新?正式激活后会发生什么情况?

    除非安装说明中另有说明,否则官方更新可能会导致无法激活。 要从本网站更新软件,您需要在此处下载此软件的新版本(如果可用),并将其安装在计算机上安装的版本之上(替换)。在这种情况下,您将保存此软件的激活和设置。

  • 如何下载?链接不起作用?

    我们使用百度网盘,132云盘和微软网盘,除了百度网盘,其他两款不限速,如果链接失效,请您联系客服处理

  • 已发布更新。我什么时候升级我的版本?

    所有软件如有更新,我们第一时间推送,视自己情况更新使用

  • 如何更改语言?

    打开“系统偏好设置”->“通用>语言和地区”->应用程序-“+”。 选择应用和语言。此方法适用于大多数应用程序。 Adobe 产品中的语言通常是在产品本身的安装阶段选择的。 游戏中的语言通常会在游戏本身的设置中发生变化。

  • 如何删除软件?

    有很多选择。最简单的方法是使用特殊的实用程序来卸载应用程序,例如App Cleaner Uninstaller 要删除 Adobe 产品,请使用 Creative Cloud Cleaner Tool

  • 需要远程帮助吗?

    网站已开通永久会员的可享受免费远程,如果非永久会员,远程安装另外收费

点点赞赏,手留余香

给TA打赏
共0人
还没有人赞赏,快来当第一个赞赏的人吧!
    技术教程

    第二章:既有面向过程,为何还要面向对象,了解C++程序的基本构成,快速入门指南

    2024-2-11 10:32:00

    技术教程

    第四章:C++比C加了什么,了解C++程序的基本构成,快速入门指南

    2024-2-13 13:01:08

    0 条回复 A文章作者 M管理员
    愿你出走半生,归来仍是少年
    欢迎您,新朋友,感谢参与互动!
      暂无讨论,说说你的看法吧
    后退
    榜单