c++ - extern "C"按着别人博客写的测试程序总是报错?
大家讲道理
大家讲道理 2017-04-17 15:03:40
0
2
654

三个文件:

/* c语言头文件:cExample.h */
#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H
extern int add(int x,int y);     //注:写成extern "C" int add(int , int ); 也可以
#endif
/* c语言实现文件:cExample.c */
#include "cExample.h"
int add( int x, int y )
{
 return x + y;
}
// c++实现文件cppFile.cpp,调用add
extern "C"
{
#include "cExample.h"
}
//注:此处不妥,如果这样编译通不过,换成 extern "C" int add(int , int ); 可以通过
extern "C" int add(int, int);
int main(int argc, char* argv[])
{
    add(2, 3);
    return 0;
}

这都是别人博客的代码,他说不会错,然后我在VS2015运行了,报错,错误 LNK2019 无法解析的外部符号 _add,该符号在函数 _main 中被引用。我换了好几个人博客把代码复制进去都是报同样的错误,我不知道是什么问题,上面注释里的我也试了还是报错。

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

全部回复(2)
Peter_Zhu

找到错误了,

我没有把.c和.h拖至工程里,只是放在该目录下了。已解决。

Ty80

刚看到,楼主已经自己解决了问题。不过,这个例子在 gcc 这里还是错的:

$ g++ -std=c++11 -pedantic -Werror cExample.c cppFile.cpp -o demo
/tmp/cceHYgc4.o: In function `main':
cppFile.cpp:(.text+0xf): undefined reference to `add'
collect2: error: ld returned 1 exit status

这是因为 c++ 编译器在编译 cExample.c 的时候,虽然你的意图是调用 C 编译器去编译 add 函数的代码,但是 c++ 编译器并不知道这些,它认为 add 函数是一个 c++ 函数,于是,编译后 add 函数的名字会被改为 _Z3addii。这样,即使你在 cppFile.cpp 文件中指定要使用 C 版本的 add 函数,但是这个函数事实上不存在,所以就出现了无法解析的外部符号。

要解决这个问题,只需要在 cExample.h 文件中这样写:

#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H
extern "C" {
        int add(int x, int y);
}
#endif

如果 cExample.h 中声明的函数要被其他 C 模块调用,那么严谨的写法是:

#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H
#ifdef __cplusplus
extern "C" {
#endif

int add(int x, int y);

#ifdef __cplusplus
}
#endif
#endif

至于为什么在 VS 中将 cExample.{h,c} 拖到工程中就可以解决问题,这就不得而知了。猜测是 VS 遇到文件后缀名为 .c 的文件,就自动用 C 编译器去编译。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板