C和C++的混编问题


前言

C和C++混编问题也是我在实际的开发过程中遇到的问题,由于编译器会根据源代码的后缀,自动选择C或者C++编译器。所以这个问题不小心的话,很容易忽略。


一、问题出现的背景

在某次开发中,我在工程中添加了两个源文件,一个后缀为.c,一个后缀为.cpp。
在CPP文件中实现了某个函数,在C文件中调用该函数。源码示例如下:

add.cpp

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

main.c

void main(void)
{
	int c=0;
	c = add(1,2);
}

使用命令单独编译两个文件,是没有报错的。
gcc -c add.cpp -o add.o
gcc -c main.c -o main.o

但是当将两个.o文件,进行链接时,就会出现,无法链接add函数的问题。

二、问题出现的原因

根本的原因是,c编译器和c++编译器对于链接文件中的函数名修饰规则不同。初次听到这些名词,可能一脸懵。 什么叫函数名修饰?
简单的说,编译过程是先将各个c或者c++源文件编译成.o文件。再将各个.o文件链接成可执行文件。 链接的时候是通过符号识别的方式,链接到正确的函数。

比如在main函数中调用了add函数,main函数就需要通过符号识别,找到add.cpp
文件中定义了add函数,从而将add的代码链接过来。

在将.c和.cpp编译成.o文件时,编译器会将函数名加上修饰,从而形成链接时用的符号。 举个例子,add函数编译完成后的符号是"_Z3addii “(各个编译器对于函数的修饰方案都不同,这个只是示例)。
同时要提醒一下,同一个编译器对于c文件和c++文件的函数名修饰方法也不同。
如果add函数在c文件中,修饰后的符号可能是”_add"。

由于c和c++的修饰方案不同,所以问题就出现了。main函数在c文件中,它调用add函数是用"_add"符号。而add函数是在c++文件中,它修饰完的符号不是"_add"。
所以报链接错误。

三、解决办法

使用extern "c"将c++文件中的函数包起来。 这样就告诉了编译器,这个函数要使用c文件的修饰方式,去修饰。代码如下:

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

这样编译出来的符号,就可以和main函数匹配上了。


总结

本文主要讲了c和c++文件混合编译的问题。比较简单。详细的可以参考我的另一篇文章,单独讲extern "C"的。
C语言基础:extern "C"语句的作用

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值