关于如何进行C/C++混合编程的问题(在C程序里调用C++库或在C++程序里调用C库)

最近在工作在遇到需要在C语言程序里调用C++库的问题,这次将这个问题总结记录一下。

1、关于为什么需要C和C++混合编程

        我们知道C语言和C++各自有更适合的领域,比如在嵌入式开发中,底层操作系统以及音视频开发通常使用C语言,而应用层开发通常使用的是C++。

2、为什么不同的语言可以混合编程

(1)程序编译的过程:高级语言->汇编语言->二进制代码->链接->可执行程序->烧录镜像;
(2)任何语言最终都要变成二进制的可执行程序才能在CPU上运行,不同的高级语言在编译成汇编语言的过程是不一样的,所以每种高级语言都有自己的编译器;
(3)不管哪种高级语言在汇编语言阶段或者二进制代码阶段时都是一样的格式,互相之间是可以调用的,也就是我们常看到的库文件,开发中常把代码编译成库供其他人调用;
(4)高级语言的目标都是编译成汇编指令,汇编指令是和CPU相关而与高级语言无关,所以CPU相同的情况下,每种高级语言在汇编阶段都是统一的;

3、解决思路

       在实际编程中我们通常认为C++是对C语言的扩充和延申,并且对C语言提供后向兼容的能力。C++支持的某些特性在C语言中并不支持,所以C++在需要和C对接的部分不能采用C++的特性,而应该使用C语言的风格来编写代码。

        依据这一思路,可以在C++中使用extern “C”{}将需要和C对接的部分括起来,表示该部分向C兼容。

3.1、extern “C”{}使用示例

#ifdef __cplusplus
extern "C"{
#endif

	······

#ifdef __cplusplus
}
#endif

4、C++调用C:C是库

4.1.、C函数代码:cTest.c

int add(int a, int b)
{
	
	return a+b;
	
}

4.2、C头文件:cTest.h

#ifndef __CTEST_H__
#define __CTEST_H__

#ifdef __cplusplus
extern "C"{
#endif

int add(int a, int b);

#ifdef __cplusplus
}
#endif

#endif

4.3、C++调用代码:cppTest.cpp

#include <iostream>
#include "cTest.h" 

using namespace std;

int main()
{
	int a = 1;
	int b= 2;
	
	cout << add(a, b) << endl;
	
	return 0;
}

4.4、编译链接代码

4.4.1、使用extern “C”{}
[root#]$ ls
cppTest.cpp  cTest.c  cTest.h  
[root#]$ 
[root#]$ gcc -c cTest.c -o cTest.o
[root#]$ 
[root#]$ ar -r libcTest.a cTest.o	
ar: creating libcTest.a
[root#]$ 
[root#]$ g++ cppTest.cpp -L. -lcTest
[root#]$ 
[root#]$ ls
a.out  cppTest.cpp  cTest.c  cTest.h  cTest.o  libcTest.a
[root#]$ 
[root#]$ ./a.out 
3
4.4.2、不使用extern “C”{}
root#]$  g++ cppTest.cpp -L. -lcTest
/tmp/cc0Wckzc.o: In function `main':
cppTest.cpp:(.text+0x21): undefined reference to `add(int, int)'
collect2: ld returned 1 exit status

报错!!

总结:用C语言写功能库代码时,需要对外提供的函数接口头文件用extern “C”{}括起来,将来库无论被C语言调用还是被C++调用都支持。

5、C调用C++:C++是库

5.1、C++函数代码:cppTest.cpp
#include "cppTest.hpp"

int add(int a, int b)
{
	
	return a+b;
	
}

5.2、C++头文件:cppTest.hpp

#ifndef __CPPTEST_HPP__
#define __CPPTEST_HPP__

int add(int a, int b);

#endif

5.3、C调用代码:cTest.c

#include <stdio.h>
#include "cppTest.hpp" 

int main()
{
	int a = 1;
	int b= 2;
	
	printf("a+b=%d\n", add(a, b));
	
	return 0;
}

这样会报错

5.4、解决方案:将C++库再封装一层wrapper文件

5.4.1、封装的C++源文件:cppPack.cpp
#include "cppPack.hpp"
#include "cppTest.hpp"

int addPack(int a, int b)
{
	
	return add(a, b);
	
}
5.4.2、封装的C++头文件:cppPack.hpp
#ifndef __CPPPACK_HPP__
#define __CPPPACK_HPP__

#ifdef __cplusplus
extern "C"{
#endif

int addPack(int a, int b);

#ifdef __cplusplus
}
#endif

#endif
5.4.3、C调用代码:cTest
#include <stdio.h>
#include "cppPack.hpp" 

int main()
{
	int a = 1;
	int b= 2;
	
	//这里调用封装的addPack函数,addPack函数内部就是调用的add函数
	printf("a+b=%d\n", addPack(a, b));
	return 0;
}
5.4.4、编译链接代码
root@ubuntu:# g++ cppPack.cpp -c -o cppPack.o
root@ubuntu:# ar -r libcppPack.a cppPack.o
root@ubuntu:# gcc cTest.c -L ./ -lcppPack -lcppTest -I ./

成功!!

参考博客:【C++入门】C和C++混合编程超详细讲解-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值