设为首页 - 加入收藏 邵阳站长网 (http://www.0739zz.com)- 国内知名站长资讯网站,提供最新最全的站长资讯,创业经验,网站建设等!
热搜: 系统 什么 为什么 芯片
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

C++中是如何调用C接口的?

发布时间:2019-08-30 06:07 所属栏目:[优化] 来源:守望先生
导读:如何在C++代码中调用写好的C接口?你可能会奇怪,C++不是兼容C吗?直接调用不就可以了?这里我们先按下不表,先看看C++如何调用C代码接口。 C++如何调用C接口 为什么会有这样的情况呢?想象一下,有些接口是用C实现的,并提供了库,那么C++中该如何使用呢?我们

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

C++/C接口

C++如何调用C接口

为什么会有这样的情况呢?想象一下,有些接口是用C实现的,并提供了库,那么C++中该如何使用呢?我们先不做任何区别对待,看看普通情况下会发生什么意想不到的事情。

首先提供一个C接口:

  1. #include"test.h"?
  2. void?testCfun()?
  3. {?
  4. ????printf("I?am?c?fun\n");?
  5. ????return;?
  6. }?

为了简化,我们在这里就不将它做成静态库或者动态库了,我们在这里编译成C目标文件:

  1. gcc?-c?test.c?

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

  1. #include?
  2. void?testCfun();?

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

  1. #include"test.h"?
  2. #include?
  3. using?namespace?std;?
  4. int?main(void)?
  5. {?
  6. ????/*调用C接口*/?
  7. ????cout<<"start?to?call?c?function"<<>
  8. ????testCfun();?
  9. ????cout<<"end?to?call?c?function"<<>
  10. ????return?0;?
  11. }?

编译:

  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?
  2. extern?"C"{?
  3. void?testCfun();?
  4. }?

这里用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接口要被代码调用呢?增加main.c内容如下

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

编译:

  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"{?

【免责声明】本站内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

网友评论
推荐文章