C语言调用C++类成员函数讲解和实例
  BUniBU6Nn1a2 2023年12月04日 25 0

1、问题成因

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

2、反汇编证明

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

int funP(int a)
 
{
 
return 0;
 
}
  
  
 
int main()
 
{
 
int a = 0,ret;
 
ret = funP(a);
 
return 0;
 
}

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

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

对可执行程序进行反汇编

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

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

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

3、C++程序

3.1、add.h

#define ADD_H
  
  
 
class addCode
 
{
 
public:
 
addCode();
 
~addCode();
  
  
 
void setNum(int a); 
 
int getNum();
 
private:
 
int m_a; 
 
};
  
  
 
#endif

3.2、add.cpp

#include "add.h"
  
  
 
addCode::addCode()
 
{
 
m_a = 0;
 
}
  
  
 
addCode::~addCode()
 
{
 
}
  
  
 
void addCode::setNum(int a)
 
{
 
a++;
 
printf("c++ a = %d\n",a);
 
m_a = a;
 
}
  
  
 
int addCode::getNum()
 
{
 
return m_a;
 
}

4、中间封装程序

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

4.1、myadd.h

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

#define MYADD_H
  
  
 
#ifdef __cplusplus
 
extern "C"{
 
#endif
  
  
 
typedef struct addCode addCode;
 
addCode* newAddCode();
 
void interSetNum(addCode *v,int a);
 
int interGetNum(addCode *v);
  
  
 
#ifdef __cplusplus
 
}
 
#endif
 
#endif

4.2、myadd.cpp

#include "myadd.h"
  
  
 
extern "C"{
 
addCode* newAddCode(){
 
return new addCode();
 
}
  
  
 
void interSetNum(addCode *v,int a)
 
{
 
v->setNum(a);
 
}
  
  
 
int interGetNum(addCode *v)
 
{
 
return v->getNum();
 
}
 
}

5、C语言主程序 main.c

#include "myadd.h"
  
  
 
int main(void)
 
{
 
int a = 1;
  
  
 
struct addCode* v = newAddCode();
 
//传递参数给C++
 
interSetNum(v,a);
 
printf("main a = %d\n",a);
  
  
 
//获取C++中参数值
 
a = interGetNum(v);
 
printf("main get a = %d\n",a);
  
  
 
return 0;
 
}

6、编译执行

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

g++ -c myadd.cpp -o myadd.o
 
gcc -c main.c -o main.o
 
g++ add.o myadd.o main.o -o test

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

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

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



【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月04日 0

暂无评论

推荐阅读
BUniBU6Nn1a2