如何使用编译的C代码编译和链接C ++代码?

我希望能够使用Cmockery来模拟从我正在测试的C ++代码调用的C函数。 作为向前迈出的一步,我将Cmockery示例run_tests.c重命名为run_tests.cpp,并尝试编译并将其与cmockery.c链接:

g++ -m32 -DHAVE_CONFIG_H -DPIC -I ../cmockery-0.1.2 -I /usr/include/malloc -c run_tests.cpp -o obj/run_tests.o gcc -m32 -DHAVE_CONFIG_H -DPIC -Wno-format -I ../cmockery-0.1.2 -I /usr/include/malloc -c ../cmockery-0.1.2/cmockery.c -o obj/cmockery.o g++ -m32 -o run_tests obj/run_tests.o obj/cmockery.o 

前两个命令行(编译)是成功的,但在最后我得到:

 Undefined symbols: "_run_tests(UnitTest const*, unsigned long)", referenced from: _main in run_tests.o ld: symbol(s) not found collect2: ld returned 1 exit status 

该未定义的符号来自run_tests.cpp的第29行:

 return run_tests(tests); 

run_tests()函数在cmockery.c中定义。

在阅读“ 使用’gcc’链接C ++代码(没有g ++) ”之后,我尝试了:

 gcc -lstdc++ -m32 -o run_tests obj/run_tests.o obj/cmockery.o 

但得到了相同的结果:

 Undefined symbols: "_run_tests(UnitTest const*, unsigned long)", referenced from: _main in run_tests.o ld: symbol(s) not found collect2: ld returned 1 exit status 

如何编译和链接C ++代码,以便在C代码中找到符号?

我认为你可以通过在cmockery.h文件的内容周围添加以下内容来使thinkgs从C ++链接:

在开头或附近:

 #if defined(__cplusplus) extern "C" { #endif 

在结束时或附近:

 #if defined(__cplusplus) } #endif 

这样,在C源代码中使用头文件将忽略声明的extern "C"部分,但是当在C ++构建中包含头部时,编译器将被正确地告知该头部中的声明的链接使用C语义。

对于快速肮脏的测试,或者如果您不想修改标题,可以尝试:

 extern "C" { #include "cmockery.h" } 

但我的偏好是将extern "C"块放在标题中(并且只在需要的东西周围 – 这可能需要一些分析)。

在C ++代码包含的头文件中,需要对用C编译的所有函数进行extern "C"声明。

当你从C ++中包含C头文件时,你是否用extern "C" { .... }包装了原型? 如果不这样做,C ++函数名称将在链接时被“损坏”。

正如卡尔所说,需要extern "C" { .. }

原因是:C ++破坏名称(添加有趣的字符),以便链接是类型安全的。 C没有,因此在语言中将foo(int)链接到foo(double)是可能的(但是错误和令人尴尬)。

为了成功实现互操作性,您需要告诉C ++编译器一些函数名称不会被破坏,以便链接成功。