嵌入式C/C++:对现有符号的未定义引用

Embedded C/C++: undefined reference of an existing symbol

本文关键字:符号 未定义 引用 C++ 嵌入式      更新时间:2023-10-16

我很难将我的代码链接到Atmel库。

我的代码使用Atmel库中定义的函数GetTickCount()。我的cpp文件编译正常,但链接失败。该库在链接过程中存在,并且在该过程中实际被另一个C文件使用。

  • 我的文件I2C_due.cpp调用函数GetTickCount()

  • 函数GetTickCount()存在于库libsam_sam3x8e_gcc_rel.a(来自timetick.c)中。这是Atmel的预构建文件。

  • 文件wiring.c(来自Arduino)是用我的文件编译的,也调用了GetTickCount(),但在链接之前,它被放在libFrameworkArduino.a中。

在链接过程中,链接器不会抱怨从wiring.c调用GetTickCount(),而是抱怨我的文件。如果我从链接器命令行中删除liblibsam_sam3x8e_gcc_rel.a,它当然也会抱怨wiring.c调用。所以我确信lib在链接过程中被使用(它在命令行的末尾,所以链接器首先解析我的文件)。

我想知道两件事:

  1. 我正在C++方法中调用一个C函数。

  2. 与新的C可见性功能有关。

GetTickCount()libsam_sam3x8e_gcc_rel.a中嵌入的timetick.c内定义:

extern uint32_t GetTickCount( void )
{
return _dwTickCount ;
}

timetick.h

extern uint32_t GetTickCount( void ) ;

链接器命令行:

arm-none-eabi-g++ -o .pioenvs/due/firmware.elf -Os -mthumb -mcpu=cortex-m3 
-Wl,--gc-sections -Wl,--check-sections -Wl,--unresolved-symbols=report-all 
-Wl,--warn-common -Wl,--warn-section-align -Wl,--entry=Reset_Handler -u _sbrk 
-u link -u _close -u _fstat -u _isatty -u _lseek -u _read -u _write -u _exit 
-u kill -u _getpid -Wl,-T"flash.ld" (many objects).o 
.pioenvs/due/src/Marlin/HAL/DUE/I2C_due.o (many objects).o -L(many lib dirs) 
-Wl,--start-group .pioenvs/due/libFrameworkArduinoVariant.a 
.pioenvs/due/libFrameworkArduino.a -lc -lgcc -lm -lsam_sam3x8e_gcc_rel 
.pioenvs/due/lib/libWire.a .pioenvs/due/lib/libSPI.a -Wl,--end-group

错误:

/home/alex/(longdir)/HAL/DUE/I2C_due.cpp:239: undefined reference to `GetTickCount()'
...
.pioenvs/(longdir)/HAL/DUE/I2C_due.o:/home/alex/(longdir)/HAL/DUE/I2C_due.cpp:344: more undefined references to `GetTickCount()' follow

只是库中的一个检查:

$ nm -s libsam_sam3x8e_gcc_rel.a | grep GetTickCount
GetTickCount in timetick.o
00000001 T GetTickCount

有关于如何链接我的文件的提示吗??

干杯。

亚历克斯。

通过分析R..注释,我发现了我的错误。

不允许在C++函数内部调用C函数。这就是我们在函数声明之前使用外部"C">的原因。

我必须创建.c和.h文件,并在.h 中使用外部"c">

teste.c

uint32_t MiliS()
{
return GetTickCount();
}

teste.h

extern "C" uint32_t MiliS();

这样,我们就可以从.cpp文件中调用MiliS(),它将是GetTickCount()TR的包装器