首页 > 编程语言 >C语言调用C++类成员函数讲解和实例

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

时间:2023-11-26 23:34:37浏览次数:46  
标签:函数 int addCode C++ C语言 编译器 实例 main

原文:https://blog.csdn.net/LxXlc468hW35lZn5/article/details/125701007

1、问题成因

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

2、反汇编证明

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

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

对这一段小程序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.    
  4.    
  5.   class addCode
  6.   {
  7.   public:
  8.   addCode();
  9.   ~addCode();
  10.    
  11.    
  12.   void setNum(int a);
  13.   int getNum();
  14.   private:
  15.   int m_a;
  16.   };
  17.    
  18.    
  19.   #endif

3.2、add.cpp

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

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.    
  4.    
  5.   #ifdef __cplusplus
  6.   extern "C"{
  7.   #endif
  8.    
  9.    
  10.   typedef struct addCode addCode;
  11.   addCode* newAddCode();
  12.   void interSetNum(addCode *v,int a);
  13.   int interGetNum(addCode *v);
  14.    
  15.    
  16.   #ifdef __cplusplus
  17.   }
  18.   #endif
  19.   #endif

4.2、myadd.cpp

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

5、C语言主程序 main.c

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

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

标签:函数,int,addCode,C++,C语言,编译器,实例,main
From: https://www.cnblogs.com/bruce1992/p/17858218.html

相关文章

  • 【C与C++的相互调用方法】
    原文:https://blog.csdn.net/qq_43899283/article/details/132343699C与C++的相互调用方法C与C++为什么相互调用的方式不同C++中调用CC中调用C++致谢C与C++为什么相互调用的方式不同  C和C++之间的相互调用方式存在区别,主要是由于C和C++语言本身的设计和特性不同。函数......
  • extern "C":实现C++和C的混合编程
    原文:https://c.biancheng.net/view/8064.html通过《C语言和C++到底有什么关系?》一节的学习,读者已经了解了C++和C语言之间的关系。简单的理解,C++就是在C语言的基础上增加了一些新特性,从大的方面讲,C++不仅支持面向过程编程,还支持面向对象编程和泛型编程;从小的方面讲,C++还......
  • C语言笔记7
    数组是一组有序的、类型相同的数据的集合,这些数据被称为数据的元素。一维数组的定义类型说明符数组名【正整型常量表达式】说明:类型说明符:数组的类型。数组名同变量名命名规则相同。常量表达式指明数组中元素个数,必须大于0.可以是数值常量、符号常量和字符常量。例如:floa......
  • C语言模拟进程状态
    精选状态图如下给出C语言执行状态图根据状态图,给出C语言代码解释这段代码定义了一个枚举类型ProcessState,包含了5个枚举值:NEW、READY、RUNNING、BLOCKED和TERMINATED。然后定义了一个ProcessState类型的变量process,并将其初始化为NEW。接着通过printf语句输出当前进程状态......
  • C语言【文件操作】
    C语言【文件操作】1、输入/输出流的定义。​ C语言中,文件输入/输出以流的方式进行。​ 读还是写,输入还是输出,是站在内存(程序)的角度来看的。从程序(内存)向数据源(如文件、网络等)传递数据的过程叫做读数据,读数据使用的路径叫做输入流,一般读数据的过程是一个解码的过程;从数据源(如文......
  • C++U3-第2课-基础排序(二)
    上节课作业讲师视频分享链接:百度云网盘链接:https://pan.baidu.com/s/1PFBLFdX6C-9FhKXWrhDBew?pwd=l8r3提取码:l8r3本节课教学目标 插入排序概念 插入排序的代码和思路分析  插入代码详细解释【题意分析】1.从第一个元素开始,该元素可以认为已经被排序;2.取出下......
  • C语言模拟进程状态
    首先定义进程状态的枚举类型为ProcessStatetypedefenum{NEW,READY,RUNNING,BLOCKED,TERMINATED}ProcessState;而后据图中进程运行代码intmain(){ProcessStateprocess=NEW;printf("Processcreated.State:NEW\n");process=REA......
  • C++11以及17部分特性
    1//1、并发支持2//1.1、C++11内存模型:3//a.原子性(Atomicity):对于原子类型(std::atomic),其成员函数的操作是原子的,不会被其他线程中断。4//b.可见性(Visibility):对于非原子类型,通过使用互斥量或同步操作来确保共享数据的可见性,即在一个线程中对共享数据的......
  • C++ ini 实现
    首先是从https://github.com/benhoyt/inih取用的ini读取类头文件//fileini.h/*inih--simple.INIfileparserSPDX-License-Identifier:BSD-3-ClauseCopyright(C)2009-2020,BenHoytinihisreleasedundertheNewBSDlicense(seeLICENSE.txt).Gotothe......
  • 《实例化需求》阅读笔记三
    这本书给出了做到实例化需求的关键过程模式: 从目标中获取范围——协作定制需求说明——举例说明——提炼需求说明——不需要修改需求说明的自动化验证——频繁验证——演化出一个文档系统。从目标中获取范围:交付团队不应该指望用户直接给出范围或者解决方案,因为客户大部分时候并......