Visual Studio 2022无法链接.c/.cpp混写代码但g++可正常编译问题
问题原因与解决方案说明
链接失败的核心诱因
你遇到的是C、C++混合编译时的*名字修饰(Name Mangling)*规则不匹配问题,触发逻辑如下:
- Visual Studio会根据文件后缀自动选择编译器:
.c后缀文件调用C编译器编译,.cpp后缀文件调用C++编译器编译。 - C语言无函数重载机制,C编译器编译
Source.c里的test函数调用时,生成的依赖符号名是纯函数名格式(32位为_test、64位为test)。 - C支持函数重载,C编译器编译
Source2.cpp里的test函数实现时,会给函数名加上参数类型、调用约定等后缀做修饰,生成类似?test@@YAXNNH@Z的特殊符号名,和C编译器生成的符号名完全不匹配,链接阶段就会报无法解析外部符号的错误。 - 所有文件后缀改为
.cpp后,全部文件都会走C++编译器编译,名字修饰规则统一,符号可以正常匹配,所以链接成功。
g++不报错的原因
你使用g编译时,默认会把所有输入的.c、.cpp文件都按照C语法处理,所以所有文件的名字修饰规则一致,不会出现符号不匹配问题。如果你用gcc单独编译.c文件、g++单独编译.cpp文件再链接,一样会触发和Visual Studio相同的链接错误。
无需修改后缀的解决方法
如果不想改动文件后缀,可以修改头文件声明,给C调用的函数加extern "C"修饰,统一符号生成规则:
#pragma once #include <stdio.h> #ifdef __cplusplus extern "C" { #endif void test(double arg1, double arg2, int arg3); #ifdef __cplusplus } #endif
该声明会告诉C++编译器,这个函数按照C语言规则生成符号名,和C编译器的规则对齐,即可正常链接。
内容的提问来源于stack exchange,提问作者Dresult
相关产品推荐
相关产品推荐

