c语言cpp编译,C和C++混合编译

1. 背景

为了工作需要,在抽离一个开源库组件的时候,编译成功链接却失败,查找原因发现测试文件使用的是C++语言,而库的组件使用的是C语言,具体原因记录与此。

2. 现场

为了测试,写了一个单独的简单案例:

新建win32工程,建立三个文件,分别是test.c、test.h和main.cpp。

main.cpp

#include "test.h"

int main()

{

test(1);

return 0;

}

test.h

#ifndef _TEST_H_

#define _TEST_H_

void test(int a);

#endif

test.c

#include "test.h"

void test(int a)

{

}

编译运行:

da2a07103c78

编译结果

3. 原因

编译成功,链接失败,很显然代码中已经实现了test函数,为了查找原因,直接打开vs命令行工具查看一下编译后的符号表都有什么。

进入Debug目录,执行dumpbin /SYMBOLS test.obj。

da2a07103c78

test.c 符号表

答案很显然,编译test.c生成的符号是_test,而现在要找的是void __cdecl test(int)" (?test@@YAXH@Z),结果当然是无法找到的。

为了进一步确认答案,将test.c改为test.cpp,重新编译,查看符号表。

da2a07103c78

test.cpp 符号表

对于C语言生成的符号表和C++语言生成的符号表差距很大,原因无非是C++支持了很多新的功能,原来的符号表生成规则已经无法满足。

例如:重载、多态等机制。

为了解决这个问题,C++语言引入了另一种语法来解决这个问题。

da2a07103c78

C++标准文档语法描述

4. 结论

对于C语言编写的程序来说,未来可能被C语言或者C++语言的用户所使用,大部分解决的方法是:

#ifdef __cplusplus

extern "C" {

#endif

// ...

#ifdef __cplusplus

}

#endif

直接在C语言中使用extern "C"会报语法错误,因为该语法是C++语法,对于C语言来说,声明该接口是C语言编写的显然没有任何意义,它的目标是使用C++语言的用户;而对于C++用户,该声明却是必须的,因为C和C++语言编写的函数的符号表生成结果是不一致的,除非你在编译C文件的时候明确用C++编译器,那就没什么问题了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值