嵌入式 C/C++:现有符号的未定义引用
Posted
技术标签:
【中文标题】嵌入式 C/C++:现有符号的未定义引用【英文标题】:Embedded C/C++: undefined reference of an existing symbol 【发布时间】:2017-11-18 22:30:58 【问题描述】:我很难将我的代码与 Atmel 库链接起来。
我的代码使用 Atmel 库中定义的函数 GetTickCount()。我的 cpp 文件编译正常,但链接失败。该库在链接期间存在,实际上已被进程中的另一个 C 文件使用。
我的文件 I2C_due.cpp 调用函数 GetTickCount()。
函数 GetTickCount() 存在于库 libsam_sam3x8e_gcc_rel.a 中(来自 timetick.c)。这是来自 Atmel 的预构建文件。
wiring.c 文件(来自 Arduino)是用我的文件编译的,也有对 GetTickCount() 的调用,但它位于 GetTickCount() 内strong>libFrameworkArduino.a 在链接之前。
在链接期间,链接器不会抱怨从 wiring.c 对 GetTickCount() 的调用,而是抱怨我的文件。如果我从链接器命令行中删除 lib libsam_sam3x8e_gcc_rel.a,它当然也会抱怨 wiring.c 调用。所以我确定在链接期间正在使用该库(它位于命令行的末尾,因此链接器首先解析我的文件)。
我想知道两件事:
我在 C++ 方法中调用 C 函数。
与新的 C 可见性功能相关的内容。
GetTickCount() 定义在 timetick.c 内,嵌入在 libsam_sam3x8e_gcc_rel.a 中:
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
关于如何链接我的文件的任何提示??
干杯。
亚历克斯。
【问题讨论】:
缺少extern "C"
?
调用在 C++ 方法中,我不能使用 extern "C"
不在通话中。围绕声明。
yano,你可以在链接器命令行中看到“-lsam_sam3x8e_gcc_rel”。
R..,timetick.h 和 timetick.c 是库的一部分,我不打算更改它.. 它可以随时自动更新。当然我可以解决它,但我想知道“真正的”问题。
【参考方案1】:
分析 R.. 评论,我发现了我的错误。
不允许在 C++ 函数中调用 C 函数。 这就是我们在函数声明之前使用 extern "C" 的原因。
我必须创建一个 .c 和 .h 文件并在 .h 中使用 extern "C"。
teste.c:
uint32_t MiliS()
return GetTickCount();
teste.h:
extern "C" uint32_t MiliS();
这样我们可以从 .cpp 文件中调用 MiliS(),它会成为 GetTickCount()
的包装器【讨论】:
关于extern "C"的好讨论:***.com/questions/1041866/… 而不是修改 teste.h(从 C 中中断使用它),您应该将extern "C"
放在 #include
周围。
再次感谢@R.. 实际上我用编译标志 __cplusplus 包装了 extern "C"。相同的结果.. 感谢您指导我找到解决方案。
关于该主题的更多文档:isocpp.org/wiki/faq/mixing-c-and-cpp以上是关于嵌入式 C/C++:现有符号的未定义引用的主要内容,如果未能解决你的问题,请参考以下文章
架构 i386“CScanner::CScanner(void*)”的未定义符号,引用自
架构 arm64 的未定义符号:FBSDK View Hierarchy 引用自:FBSDK Marketing Kit
对符号“sem_close@@GLIBC_2.2.5”的未定义引用
架构 i386 的未定义符号:“_deflate”,引用自 libMo.a 中的 PlatCompress(enumCompressOperation, CompressCookie*, void*,