如何让一个 C 语言项目调用另一个 C++ 项目中某些类所提供的接口?_一个c文件调用另一个c文件(1)

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

3、C++调用C

我们创建3个文件,分别为main.cppcal.ccal.h

img

我们分别使用gccg++单独编译文件,编译出cal.omain.o两个中间文件,很简单,定义了一个embedded_art的函数。

# dong @ ubuntu in ~/WorkSpace/Donge\_Programs/Unix\_Programming\_Learning/c\_c++\_call\_test on git:main x [15:57:32] 
$ ls
cal.c  cal.h  main.cpp

# dong @ ubuntu in ~/WorkSpace/Donge\_Programs/Unix\_Programming\_Learning/c\_c++\_call\_test on git:main x [15:57:43] 
$ gcc -c cal.c 

# dong @ ubuntu in ~/WorkSpace/Donge\_Programs/Unix\_Programming\_Learning/c\_c++\_call\_test on git:main x [15:57:49] 
$ g++ -c main.cpp 

# dong @ ubuntu in ~/WorkSpace/Donge\_Programs/Unix\_Programming\_Learning/c\_c++\_call\_test on git:main x [15:57:55] 
$ ls
cal.c  cal.h  cal.o  main.cpp  main.o

下面看一下编译之后的中间文件cal.omain.o的符号表,看看同一个函数embedded_art不同编译方式之后的差别。

img

可以看到,g++编译之后,对函数名称进行了加工,按照自身的编译规则,最终生成了一个新的函数名,所以我们如果直接调用cal.c中的embedded_art肯定是不行的。

正确方式

使用extern "C"来使g++编译器用C的方式编译。

main.cpp文件中,我们引入cal.h的位置,添加extern "C"

extern "C" {
#include "cal.h"
}

再次进行编译,即可!

img

可以看到符号表中,该函数名称正常,然后我们将中间文件链接起来,执行,输出正确结果!

# dong @ ubuntu in ~/WorkSpace/Donge\_Programs/Unix\_Programming\_Learning/c\_c++\_call\_test on git:main x [16:18:36] 
$ g++ main.o cal.o 

# dong @ ubuntu in ~/WorkSpace/Donge\_Programs/Unix\_Programming\_Learning/c\_c++\_call\_test on git:main x [16:19:54] 
$ ls
a.out  cal.c  cal.h  cal.o  main.cpp  main.o

# dong @ ubuntu in ~/WorkSpace/Donge\_Programs/Unix\_Programming\_Learning/c\_c++\_call\_test on git:main x [16:19:57] 
$ ./a.out 
main entry
嵌入式艺术

4、C调用C++

我们创建3个文件,分别为main.ccal.cppcal.h

img

我们分别使用gccg++单独编译文件,编译出cal.omain.o两个中间文件,很简单,同样定义了一个embedded_art的函数。

# dong @ ubuntu in ~/WorkSpace/Donge\_Programs/Unix\_Programming\_Learning/c\_c++\_call\_test/c\_call\_c++ on git:main x [16:24:45] 
$ g++ -c cal.cpp   

# dong @ ubuntu in ~/WorkSpace/Donge\_Programs/Unix\_Programming\_Learning/c\_c++\_call\_test/c\_call\_c++ on git:main x [16:24:52] 
$ gcc -c main.c    

# dong @ ubuntu in ~/WorkSpace/Donge\_Programs/Unix\_Programming\_Learning/c\_c++\_call\_test/c\_call\_c++ on git:main x [16:24:56] 
$ ls
cal.cpp  cal.h  cal.o  main.c  main.o

下面看一下编译之后的中间文件cal.omain.o的符号表,看看同一个函数embedded_art不同编译方式之后的差别。

img

同样,不同的编译器处理方式不同,函数名称依旧不同!同样,需要加入extern "C"来告诉编译器按C的方式编译。

我们在cal.h的声明部分添加,然后重新编译!

extern "C" {
extern void embedded\_art(void);
}

img

可以看到符号表中,该函数名称正常,然后我们将中间文件链接起来。

img

这个时候,会出现报错extern "C",这是什么情况?

main.c文件中,引入了c++的头文件cal.h,因为"C"C++编译的时候才能识别,C语言中并没有这个关键字。

所以,我们需要在g++编译的时候去加入extern "C",而gcc编译的时候跳过,这个时候就要提到c++编译时候的特定宏__cplusplus了,相当于一个阀门了。

我们修改cal.h文件

#ifdef \_\_cplusplus
extern "C" {
#endif

extern void embedded\_art(void);


![img](https://img-blog.csdnimg.cn/img_convert/61c11bfe5744e2d9c1a6afd99e6b0989.png)
![img](https://img-blog.csdnimg.cn/img_convert/c32b3561efee3463ca249abab33bcee9.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]和\[2\]提供了两个关于C++的示例代码。这些代码展示了如何在一个使用另一个的对象,并在外部调用它们的成员函数。在这些示例A定义了一个指向B对象的指针,并在构造函数初始化了这个指针。然后,A的成员函数printB()可以访问B的成员变量b并进行打印。在主函数,我们创建了一个A的对象a,并调用了它的printB()函数来打印B的成员变量b。 引用\[3\]提供了关于使用向前声明的的注意事项。即使使用了向前声明,也不能在定义之前使用该的成员。向前声明只能用于定义指向该型的指针或引用,而不能直接使用该的成员。 根据你的问题,如果你想在一个C++项目调用一个项目,你可以使用头文件和库文件的方式进行调用。首先,你需要将另一个项目的头文件包含到你的项目,以便可以使用该项目和函数。然后,你需要链接另一个项目的库文件,以便可以正确地调用定义的函数。 具体的调用方式取决于你使用的开发环境和构建工具。你可以查阅相关文档或搜索相关教程,以了解如何在你的开发环境调用一个C++项目。 #### 引用[.reference_title] - *1* *2* *3* [c++:一个调用一个,出现未定义对象问题的解决(学习笔记)](https://blog.csdn.net/lzyphhh/article/details/114982729)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值