C语言调用C++类成员函数讲解和实例
原文:https://blog.csdn.net/LxXlc468hW35lZn5/article/details/125701007
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++两种工具进行编译:
-
gcc test.c -o testc
-
g++ test.c -o test+
对可执行程序进行反汇编
可以看到gcc编译的testc反汇编出来函数名为就是funP,而g++编译的test+反汇编出来函数名为_Z4funPi,带上了返回类型和函数参数类型。两者的不一致导致C与C++相互调用无法找到对应函数。
在C和C++混合编程中,常见的是C++调用C,这种是比较简单的,一个extern “C”{}即可解决问题。而C调用C++则是使用相对较少的,我们通过一个实例来说明C如何调用C++类成员函数。
3、C++程序
3.1、add.h
-
-
-
-
-
class addCode
-
{
-
public:
-
addCode();
-
~addCode();
-
-
-
void setNum(int a);
-
int getNum();
-
private:
-
int m_a;
-
};
-
-
-
3.2、add.cpp
-
-
-
-
-
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。
-
-
-
-
-
-
extern "C"{
-
-
-
-
typedef struct addCode addCode;
-
addCode* newAddCode();
-
void interSetNum(addCode *v,int a);
-
int interGetNum(addCode *v);
-
-
-
-
}
-
-
4.2、myadd.cpp
-
-
-
-
-
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
-
-
-
-
-
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 add.cpp -o add.o
-
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++的调用,大家可以参考。
*声明:本文于网络整理,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2020-11-26 asp.net core 知识点总结
2020-11-26 WPF 知识点总结
2020-11-26 一 · 路由事件的三种方式/策略(冒泡 直接 隧道)
2020-11-26 浅谈 asp.net core web api
2020-11-26 spring boot , spring security 安全的认证
2020-11-26 C# 插件编写