|
|
51CTO旗下网站
|
|
移步端
  • C++官方是如何调用C接口的?

    如何在C++代码中滥用写好的C接口?你可能会奇怪,C++不是兼容C吗?直接调用不就足以了?此地我们先按下不表,先看看C++如何调用C代码接口。

    笔者:刘少奇 来源:C语言与C++编程| 2020-07-31 18:33

    C++官方是如何调用C接口的?

    前言

    如何在C++代码中滥用写好的C接口?你可能会奇怪,C++不是兼容C吗?直接调用不就足以了?此地我们先按下不表,先看看C++如何调用C代码接口。

    C++如何调用C接口

    为什么会有这样的状况呢?想象一下,局部接口是用C贯彻的,并提供了库,这就是说C++官方该如何使用呢?咱们先不做其他区别对待,探望普通情况下会发生什么意想不到的作业。

    第一提供一个C接口:

          
    1. //来源:群众号【编程珠玑】 
    2. // 博客:https://www.yanbinghu.com 
    3. //test.c 
    4. #include"test.h" 
    5. void testCfun() 
    6.     printf("I am c fun\n"); 
    7.     return

    为了优化,咱们在此间就不将他做成静态库或者动态库了,有兴趣的可以参考《静态库制作》机动尝试。咱们在此间编译成C目标文件:

          
    1. gcc -c test.c 

    此外提供一个头文件test.h:

          
    1. #include<stdio.h> 
    2. void testCfun(); 

    咱们的C++代码调用如下:

          
    1. //来源:群众号【编程珠玑】 博客:https://www.yanbinghu.com 
    2. //main.cpp 
    3. #include"test.h" 
    4. #include<iostream> 
    5. using namespace std; 
    6. int main(void) 
    7.     /*租用C接口*/ 
    8.     cout<<"start to call c function"<<endl; 
    9.     testCfun(); 
    10.     cout<<"end to call c function"<<endl; 
    11.     return 0; 

    编译:

          
    1. $ g++ -o main main.cpp test.o 
    2. /tmp/ccmwVJqM.o: In function `main': 
    3. main.cpp:(.text+0x21): undefined reference to `testCfun()' 
    4. collect2: error: ld returned 1 exit status 

    很不幸,说到底的链接报错了,说找不到testCfun,但是我们确实定义了这个函数。为什么会找不到呢?如今你还会以为C++直接就足以选用C接口了吗?

    精神

    咱们都晓得,C++官方函数支持重载,而C并不支持。C++为了支持函数重载,他在“浮动”函数符号信息时,决不能仅仅通过函数名,因为重载函数的函数名都是一样的,故此他还要依据入参,命名空间等信息来确定唯一的函数签名。或者说C++浮动函数签名的措施与C不一致,故此即便是函数名一样,对于C和C++来说,它们最终的函数签名还是不一样。当然这里又是另外一回事了,咱们不细说。咱们看看两个文件里之函数符号有什么区别:

          
    1. $ nm test.o|grep testCfun 
    2. 0000000000000000 T testCfun 
    3. $ nm main.o|grep testCfun 
    4.                 U _Z8testCfunv 

    故此它们两个能链接在总共才真是奇怪了呢!名字都不同,还怎么链接?

    如何处理

    这就是说如何处理呢?很明显,咱们必须告诉链接器,这是一番C接口,而不是C++接口,故此需要加入 extern C,咱们修改test.h

          
    1. #include<stdio.h> 
    2. extern "C"
    3. void testCfun(); 

    此地用extern "C"名将testCfun接口包裹起来,告知编译器,此地的是C代码哈,你要按C代码的措施处理。再次编译:

          
    1. $ g++ -o main main.cpp test.o 
    2. $ ./main 
    3. start to call c function 
    4. I am c fun 
    5. end to call c function 

    瞧终端输出,圆满!

    多极化

    虽然上面的C接口可以把C++正常调用了,但是如果这个C接口要把C代码调用呢?增长main.c情节如下

          
    1. //main.c 
    2. #include"test.h" 
    3. int main(void) 
    4.     /*租用C接口*/ 
    5.     testCfun(); 
    6.     return 0; 

    编译:

          
    1. $ gcc -o main main.c test.c 
    2. In file included from main.c:2:0: 
    3. test.h:2:8: error: expected identifier or '(' before string constant 
    4.  extern "C"
    5.         ^ 
    6. In file included from test.c:2:0: 
    7. test.h:2:8: error: expected identifier or '(' before string constant 
    8.  extern "C"

    不出意外,又报错了,很明显,C语言中并没有extern "C"这样的打法,故此为了能有效test.c的编码既能把C++租用,也能把C租用,要求改写成下面这样:

          
    1. #include<stdio.h> 
    2. #ifdef __cplusplus 
    3. extern "C"
    4. #endif 
    5.  
    6. void testCfun(); 
    7.  
    8. #ifdef __cplusplus 
    9. #endif 

    此地通过__cplusplus宏来支配是否需要extern “C”,如果是C++玉器,这就是说extern "C"局部就会把预处理进去,这样test.c代码就足以既用于C++,也得以用于C啦。

    赶快去你的C品种代码头文件中看看,只是也有这样的编码段呢?

    题材

    为什么我们在C++代码中得以直接调用一些标准C库函数呢?即使你在main函数中滥用printf等函数,他也不会出现链接错误。因为库函数已经有了类似之拍卖了。

    如果你还是不确定,你可以先预处理:

          
    1. $ g++ -E main.i main.cpp 

    扮演生成的main.i文件中找一找,只是有extern "C"。

    总结

    C++支持重载,而C不支持,C++并未能直接调用C代码写好的接口,故此如果你的C代码想要能够把C租用,也想把C++租用,这就是说别忘了extern "C"。

    这就是说问题来了,C又该如何调用C++的接口呢?

    【义务编辑: 庞桂玉 TEL:(010)68476606】

    点赞 0
  • C++  编程语言
  • 分享:
    大家都在看
    猜你喜欢
  • 订阅专栏+更多

    大数据安全运维实战

    大数据安全运维实战

    CDH+Ambari
    共20章 | 数据陈浩

    91人口订阅学习

    实操老:Jenkins接轨交付和后续部署

    实操老:Jenkins接轨交付和后续部署

    微服务架构下的无部署
    共18章 | freshman411

    184人口订阅学习

    思科交换网络安全指南

    思科交换网络安全指南

    安全才能无忧
    共5章 | 思科小牛

    109人口订阅学习

    订阅51CTO邮刊

    点击这里查看样刊

    订阅51CTO邮刊

    51CTO劳务号

    51CTO官微

    &lt;li id="a1a29282"&gt;&lt;/li&gt;

  •     
  •