当前位置:   article > 正文

C语言调用C++类成员函数讲解和实例

c语言调用c++函数

点击蓝字

aea4d0ecab20e0ddca35c79f7d2ddc7b.png

关注我们

1、问题成因

C语言与C++调用问题原因主要在于C编译器和C++编译器的不同。C是过程式语言,C编译器编译后,函数在符号库中就是函数名,没有其他任何附加信息。而C++是对象式语言,支持函数重载,C++编译器编译后,在符号库中的名字包含了函数名、函数参数类型和函数返回类型等。因此,当两者混合编译时,会相互找不到对象。

2、反汇编证明

我们通过反汇编来证明上述问题,请看下面的例子:

  1. #include "stdio.h"
  2. int funP(int a)
  3. {
  4. return 0;
  5. }
  6. int main()
  7. {
  8. int a = 0,ret;
  9. ret = funP(a);
  10. return 0;
  11. }

对这一段小程序test.c,我们分别使用gcc和g++两种工具进行编译:

  1. gcc test.c -o testc
  2. g++ test.c -o test+

对可执行程序进行反汇编

d1e59ae2e4fb974830cbb38d842676f2.png

可以看到gcc编译的testc反汇编出来函数名为就是funP,而g++编译的test+反汇编出来函数名为_Z4funPi,带上了返回类型和函数参数类型。两者的不一致导致C与C++相互调用无法找到对应函数。

在C和C++混合编程中,常见的是C++调用C,这种是比较简单的,一个extern “C”{}即可解决问题。而C调用C++则是使用相对较少的,我们通过一个实例来说明C如何调用C++类成员函数。

3、C++程序


3.1、add.h

  1. #ifndef ADD_H
  2. #define ADD_H
  3. class addCode
  4. {
  5. public:
  6. addCode();
  7. ~addCode();
  8. void setNum(int a);
  9. int getNum();
  10. private:
  11. int m_a;
  12. };
  13. #endif

3.2、add.cpp

  1. #include <stdio.h>
  2. #include "add.h"
  3. addCode::addCode()
  4. {
  5. m_a = 0;
  6. }
  7. addCode::~addCode()
  8. {
  9. }
  10. void addCode::setNum(int a)
  11. {
  12. a++;
  13. printf("c++ a = %d\n",a);
  14. m_a = a;
  15. }
  16. int addCode::getNum()
  17. {
  18. return m_a;
  19. }

4、中间封装程序

通过中间封装程序,实现C与C++之间的转换,中间封装头文件提供给C和C++程序来调用。

4.1、myadd.h

extern “C”{ } 告诉C++编译器以C的规则来链接函数,以便C编译器之后在对象文件中找到正确的符号。#ifdef _ucplusplus 是因为C编译器不知道关键字extern。

  1. #ifndef MYADD_H
  2. #define MYADD_H
  3. #ifdef __cplusplus
  4. extern "C"{
  5. #endif
  6. typedef struct addCode addCode;
  7. addCode* newAddCode();
  8. void interSetNum(addCode *v,int a);
  9. int interGetNum(addCode *v);
  10. #ifdef __cplusplus
  11. }
  12. #endif
  13. #endif

4.2、myadd.cpp

  1. #include "add.h"
  2. #include "myadd.h"
  3. extern "C"{
  4. addCode* newAddCode(){
  5. return new addCode();
  6. }
  7. void interSetNum(addCode *v,int a)
  8. {
  9. v->setNum(a);
  10. }
  11. int interGetNum(addCode *v)
  12. {
  13. return v->getNum();
  14. }
  15. }

5、C语言主程序 main.c

  1. #include <stdio.h>
  2. #include "myadd.h"
  3. int main(void)
  4. {
  5. int a = 1;
  6. struct addCode* v = newAddCode();
  7. //传递参数给C++
  8. interSetNum(v,a);
  9. printf("main a = %d\n",a);
  10. //获取C++中参数值
  11. a = interGetNum(v);
  12. printf("main get a = %d\n",a);
  13. return 0;
  14. }

6、编译执行

为了体验过程,我们不再编写makefile,依次使用如下命令行进行编译:

  1. g++ -c add.cpp -o add.o
  2. g++ -c myadd.cpp -o myadd.o
  3. gcc -c main.c -o main.o
  4. g++ add.o myadd.o main.o -o test

编译完成,执行程序,结果如下:

84d52cbb0373705f1564710d45ed0802.png

通过上述例子,我们实现了C对C++的调用,大家可以参考。

*声明:本文于网络整理,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。

c38c426d1f345af02a573d60660c26b5.png

e920c875729e41730d15186c4fda1041.gif

戳“阅读原文”我们一起进步

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/194901
推荐阅读
相关标签
  

闽ICP备14008679号