参考:extern "C"语句在C++中的作用
一、问题描述
在编译C++程序时,遇到以下问题:
/tmp/cccZeFer.o: In function `main':
main.cpp:(.text+0xf): undefined reference to `****'
collect2: error: ld returned 1 exit status
看到错误的第一直觉是共享库出问题了,因为以前出现这个问题都是因为库没有加进来,但是反复确认过后发现共享库并没有问题。
第一:编译的时候使用-l选项包含了库文件,并且库里面的函数也存在。
第二:库确实存在,不然也不会报上面的错误了,报的错误应该是:
/usr/bin/x86_64-linux-gnu-ld: cannot find -l***
collect2: error: ld returned 1 exit status
试了各种方法都无效,百思不得其解,最后无意间发现竟然是c和c符号表不兼容导致的。
因为库是c编译的,代码是c编译的,c和c的符号表规则不一致,导致编译c时找不到符号,因此编译报错。
二、重现
准备一个库libadd.so
和一个源文件main.cpp
:
> tree
.
├── libadd
│ ├── add.c
│ ├── add.h
│ └── Makefile
├── main.cpp
└── Makefile
1 directory, 5 files
add.h
和add.c
的内容:
> cat libadd/add.h
int add(int i, int j);
> cat libadd/add.c
#include "add.h"
> cat libadd/Makefile
app:
gcc add.c -fPIC -shared -o libadd.so
编译libadd.so能够正常编译,然后编译main:
> cat main.cpp
#include "libadd/add.h"
#include <iostream>
int main() {
std::cout << add(1, 2) << std::endl;
return 0;
}
> cat Makefile
app:
g++ main.cpp -Llibadd -ladd
此时编译就报错:
/tmp/cccZeFer.o: In function `main':
main.cpp:(.text+0xf): undefined reference to `add'
collect2: error: ld returned 1 exit status
解决方案
在add.h中使用宏定义把函数声明为c导出的函数:
#ifdef __cplusplus
extern "C" {
#endif
int add(int i, int j);
#ifdef __cplusplus
}
#endif
再编译就能通过了。
此处评论已关闭