今天我们在封装传感器插件的时候,出现一个问题。将包使用cmake的方式编译生成.so文件的时候出错,collect2: error: ld return xxx undefined reference,表示某个函数A没有定义。实际上该函数A是在一个a.c中定义和实现的,同时在a.h对函数A进行了声明。函数A是在b.cpp中调用的,同时在b.h中include了a.h。
针对这个问题,有两种解决方式:
1. 将a.c改成a.cpp
首先尝试将a.c改成了a.cpp,编译后又报错,显示flock::flock(int &,int)没有定义,于是又去查找对应的头文件,一个是sys/fcntl.h。改完发现还是有这个错。于是继续查,发现在C++中要使用sys/file.h这个头文件才可以。于是引入这个头文件后编译正常。
2. 在b.h中引用extern "c"的方式引入c文件对应的头文件
原来的代码都不改,直接修改b.h将#include "a.h"改成
extern "c"
{
#include "a.h"
}
直接编译通过。
通过上述过程,我们发现。我们不能直接在cpp文件中使用.c文件中定义的函数,必须使用extern "c"的方式将其引入,目的是告诉编译器针对a.c要使用c编译器,而不是c++编译器。同时,也告诉了编译器去找c环境中的头文件,而不是c++环境中的头文件。
上述过程也就表明,在linux下,c和c++环境中有很多函数是同名的,但是参数可能不同,它们所在的位置也不一样。具体引用哪个,还得好好查查。flock(int ,int)在c++中是定义在sys/file.h中的,而在c中可能是定义在sys/fcntl.h中的。