Googletest链接被测代码时报undefined reference错误该如何解决?
问题根因
这是典型的C/C++混合编译的符号不匹配问题:
- 你的
PointCalc.c是C源文件,使用C编译器编译时,函数符号会保留原始的纯函数名,不会添加参数类型相关的修饰 - 测试文件是
.cc后缀的C源文件,C编译器为了支持函数重载,会对所有函数名按照C++规则做名字修饰,添加参数类型相关的后缀 - 两边的符号名不一致,就会出现链接阶段找不到定义的错误。同一源文件内调用无异常是因为同属C++编译单元,符号修饰规则完全一致。
排查验证方法
使用nm命令查看两个目标文件的符号即可确认问题:
- 查看C编译的PointCalc.o符号:
nm ./VirtualWall/PointCalc.o | grep multiplyInteger
输出应为纯函数名,格式类似:00000000 T multiplyInteger - 查看C++编译的测试文件符号:
nm ./tests/scaleSignalTests.o | grep multiplyInteger
输出会是带修饰的字符串,格式类似:U _Z15multiplyIntegeriiiP
两个输出的符号名不一致即可确认是名字修饰不匹配导致的问题。
修复方案
方案1(推荐):修改头文件添加C++兼容声明
在PointCalc.h中添加条件编译的extern "C"包裹,让C++编译器识别到这些函数是C编译的,不会做名字修饰:
#ifndef POINT_CALC_H #define POINT_CALC_H #include "checks.h" #define INT_FACTOR_TO_METER 1000 // 新增C++兼容声明 #ifdef __cplusplus extern "C" { #endif enum Return_codes { RTN_NO_ERR = 0, RTN_UNKNOWN, RTN_OUTPUT_ERR, RTN_MEMORY_ERR, RTN_INPUT_ERR, RTN_RANGE_ERR, RTN_VALIDATION_ERR }; typedef struct sPoint { int x; int y; int z; } sPoint; int multiplyInteger(int a, int b, int *result); int addPoints(sPoint const *a, sPoint const *b, sPoint *sum); int subPoints(sPoint *minuend, sPoint *subtrahend, sPoint *diff); int mulPoints(int factor, sPoint *Point, sPoint *product); // 新增C++兼容声明收尾 #ifdef __cplusplus } #endif #endif
该方案不影响原有C代码的编译使用,是C/C++混编场景的通用解决方案。
方案2:统一编译语言
直接将PointCalc.c重命名为PointCalc.cc,使用C++编译器编译该文件,两边符号修饰规则一致即可解决问题。如果你的C代码还需要给其他纯C项目调用,不推荐使用该方案。
内容的提问来源于stack exchange,提问作者Kami Kaze
相关产品推荐
相关产品推荐

