使用avr-gcc编译器/链接器对链接的avrfix库中函数的未定义引用
undefined references to functions in linked avrfix library using avr-gcc compiler/linker
我正在尝试在项目中使用avrfix库,使用Eclipse(v4.2.2)作为IDE,使用avr-gcc作为编译器。头文件(avrfix.h)和库文件(libavrfix.a)都包含在同一目录中,该目录位于项目的搜索路径和链接器的库搜索路径中。编译时,我得到以下错误:
D:DocumentsArduinoIMU_KalmanRelease/../HMC5883/HMC5883.cpp:359: undefined reference to `lsincoslk(long, long*)'
D:DocumentsArduinoIMU_KalmanRelease/../HMC5883/HMC5883.cpp:360: undefined reference to `lsincoslk(long, long*)'
D:DocumentsArduinoIMU_KalmanRelease/../HMC5883/HMC5883.cpp:361: undefined reference to `lmullkD(long, long)'
D:DocumentsArduinoIMU_KalmanRelease/../HMC5883/HMC5883.cpp:362: undefined reference to `lmullkD(long, long)'
D:DocumentsArduinoIMU_KalmanRelease/../HMC5883/HMC5883.cpp:365: undefined reference to `lmullkD(long, long)'
D:DocumentsArduinoIMU_KalmanRelease/../HMC5883/HMC5883.cpp:365: undefined reference to `lmullkD(long, long)'
D:DocumentsArduinoIMU_KalmanRelease/../HMC5883/HMC5883.cpp:365: undefined reference to `lmullkD(long, long)'
./HMC5883/HMC5883.o:D:DocumentsArduinoIMU_KalmanRelease/../HMC5883/HMC5883.cpp:367: more undefined references to `lmullkD(long, long)' follow
./HMC5883/HMC5883.o: In function `HMC5883::Calc_Heading(long, long)':
D:DocumentsArduinoIMU_KalmanRelease/../HMC5883/HMC5883.cpp:369: undefined reference to `latan2lk(long, long)'
make: *** [IMU_Kalman.elf] Error 1
我理解这意味着链接器没有正确查找和链接有问题的函数(lsincoslk、lmullkD、lata2lk)。这些函数应该位于avrfix库中。完整地说,这里是使用的链接器调用:
avr-gcc -Os -Wl,--gc-sections -Wl,-Map,"IMU_Kalman.map",--cref --export-all-symbols -L"D:DocumentsArduinoIMU_Kalmanavrfix" -L"D:DocumentsArduinoIMU_KalmanBoard_Support_Library" -mmcu=atmega328p -o"IMU_Kalman.elf" ./Wire/Wire.o ./Wire/twi.o ./SPI/SPI.o ./MPU6000/MPU6000.o ./Kalman_Filters/GyroKalman.o ./HMC5883/HMC5883.o ./GlobalVariables.o ./IMU_Kalman.o -lavrfix -lArduino_Duemilanove_w__ATmega328 -lm
这里的重要部分是包含了-lavrfix命令。我知道链接器能够找到那个库,因为如果我尝试拼写错误的avrfix,它会出现找不到库的错误,而不是上面提到的错误。值得一提的是,我使用了我认为相同的方法,成功地包含了libArduino_Duemilanove_w__ATmega328.a库。
当我查看编译器生成的.map文件时,我确实看到了来自Arduino_Duemilanove_w__ATmega328库的几个函数,正如预期的那样(例如malloc)。然而,avrfix库中似乎没有任何函数或对象进入地图。在.map文件中搜索"avrfix"只会产生一行内容:
LOAD D:DocumentsArduinoIMU_Kalmanavrfixlibavrfix.a
链接顺序可能有问题吗?我不知道这里可能出了什么问题。是否由于某种原因,avrfix库与我正在使用的avr-gcc编译器不兼容?我也有点不熟悉二进制解析器(或者它们是否与我的问题有关),但我已经尝试在项目属性的C/C++构建->设置->二进制解析器选项卡中选择多个不同的解析器(包括GNU Elf Parser)。有关更多信息,我在github上有整个项目(尽管这是一项正在进行的工作,处于早期阶段)。我试着在其他线程中寻找帮助,但在我的应用程序中似乎找不到太多特定于avrfix库的信息。在另一个线程中,我发现了在链接器调用中使用--export-all-symbol选项的建议,但这似乎对我的情况没有帮助。
如果有人知道发生了什么事,请帮忙!不要犹豫,向我索取更多信息。
问候,
Paul
对"lsincoslk(long,long*)"的未定义引用
这是对C++
损坏名称的引用。
libavrfix.a
很可能将该符号定义为未修饰的C
名称。你可以通过运行来验证这一点
avr-readelf -Ws libavrfix.a | grep lsincoslk
如果你看到NNNN T _Z9lsincoslklPl
,我的猜测是错误的。但如果你看到NNNN T lsincoslk
,那么我的猜测是正确的。
看看这个版本的avrfix.h
,我发现它缺少适当的extern "C"
保护。当您将此标头包含到C++
中时,必须执行以下操作:
extern "C" {
#include "avrfix.h"
}
如果avrfix
开发人员关心C++
,您就不必这么做了。你可以给他们发一个补丁到avrfix.h
。补丁应该在开始时添加以下内容:
#ifdef __cplusplus
extern "C" {
#endif
最后这个:
#ifdef __cplusplus
}
#endif
- 内联函数中具有内部链接的全局变量
- 使用C链接在函数内部创建C++模板
- 返回一个带有 std::move 的对象并链接函数
- 无法使函数公开。获取:"LNK2005"错误。如何调试链接器错误
- 链接器错误:无法解析构造函数
- C++线程找不到函数作为参数(链接器)
- 使用动态链接加载程序 <dlfcn.h> 而不是直接函数调用的目的是什么?
- 构造函数的链接时间自动注册
- Doxygen:不为非成员函数生成超链接
- 静态库中的 g++ 错误链接函数
- 编写链接函数的更短/更有效的方法,该函数按字典顺序添加新元素
- 仅当链接函数 C++ 时,才会发生"Expression must have class type error"
- 反向动态链接函数调用
- OpenGL GLX_EXT_swap_control存在,但无法链接函数
- C++哈希链接函数
- c++中对链接函数的未定义引用
- 在运行时用LD_PRELOAD链接函数
- C++标准是否规定C链接函数为“noexcept”
- 可以用不同的名称链接函数
- 共享库没有链接函数