gpt4 book ai didi

c++ - 将 C++ 链接到静态库; undefined reference 错误

转载 作者:行者123 更新时间:2023-11-30 00:44:24 28 4
gpt4 key购买 nike

我正在尝试将一个小型 C++ 测试程序 main.o 链接到第 3 方静态库,但出现一些莫名其妙的 undefined reference 错误。

具体来说:

g++  -o secoTest -lpthread  main.o  libEAPI.a
main.o: In function `main':
main.cpp:(.text+0x29fe): undefined reference to `EApiWDog_SetConfigAndStart(unsigned int, unsigned int, unsigned int, unsigned int, unsigned char, unsigned char, unsigned char)'
main.cpp:(.text+0x33fc): undefined reference to `EApiSetCarrier(unsigned char)'
main.o:main.cpp:(.text+0x3956): more undefined references to `EApiSetCarrier(unsigned char)' follow
main.o: In function `main':
main.cpp:(.text+0x3965): undefined reference to `EApiGPIOGetSerialCfg(unsigned char*)'
main.cpp:(.text+0x3a0a): undefined reference to `EApiSetCarrier(unsigned char)'
main.cpp:(.text+0x3a19): undefined reference to `EApiGPIOSetSerialCfg(unsigned char)'
main.cpp:(.text+0x3adf): undefined reference to `EApiFanEnable(unsigned int, unsigned char)'
main.cpp:(.text+0x3b83): undefined reference to `EApiFanDisable()'
collect2: ld returned 1 exit status

但是,这些符号似乎 存在于库中。例如:

nm --demangle libEAPI.a | grep EApiFanDisable
00003c20 T EApiFanDisable

奇怪的是这些符号并不完全相同。在 main.o 中是

nm --demangle main.o | grep EApiFanDisable
U EApiFanDisable()

所以一个有 () 而一个没有。

同样,

nm --demangle main.o | grep EApiSetCarrier
U EApiSetCarrier(unsigned char)
nm --demangle libEAPI.a | grep EApiSetCarrier
000015d0 T EApiSetCarrier

如果我在命令行中完全省略库(例如,g++ -o secoTest -lpthread main.o),它会按预期显示很多错误。

main.o() 引用外部符号 [为什么?]:

     U EApiVgaSetBacklightEnable
U EApiWDogStart
U EApiWDogTrigger
U EApiFanEnable(unsigned int, unsigned char)
U EApiFanDisable()
U EApiSetCarrier(unsigned char)

但是库只有符号没有 () [为什么?]:

000020e0 T EApiVgaSetBacklightEnable
000024e0 T EApiWDogStart
000026f0 T EApiWDogTrigger
00003c20 T EApiFanDisable
00003bf0 T EApiFanEnable
000015d0 T EApiSetCarrier

这会是 undefined reference 的原因吗?我将如何解决它?不确定下一步要看哪里...

(我不能修改第 3 方库,但有头文件。)

编辑

正如 lisyarus 所建议的,这里是没有 --demanglenm。确实,符号不同。 g++ 编译器 (v4.4.7) 生成一个错位符号仅针对某些符号,而库始终具有纯符号...[为什么?]

nm libEAPI.a main.o | grep EApiWDogTrigger
000026f0 T EApiWDogTrigger
U EApiWDogTrigger
nm libEAPI.a main.o | grep EApiSetCarrier
000015d0 T EApiSetCarrier
U _Z14EApiSetCarrierh

最佳答案

libEAPI.a 包含用 C 而不是 C++ 编译的目标文件。因此,这些符号没有被命名,不能用于解析由 C++ 生成的名称错误的函数引用代码。

运行:

nm libEAPI.a | grep EApiFanDisable

您将看不到任何变化。

运行:

nm main.o | grep EApiFanDisable

你会看到被破坏的符号,它既不是 EApiFanDisable 也不是 EApiFanDisable()但更像是 _Z14EApiFanDisablev,链接器实际上正在尝试解决。

为避免这些链接错误,您必须通知您的 C++ 编译器,当它编译 libEAPI 的头文件,其中的声明有外部 C 链接,因此它将发出对声明的符号的未损坏引用:像这样:

main.cpp

...
extern "C" {
#include "EAPI.h" // or whatever
}

...

顺便说一句,这个命令行:

g++  -o secoTest -lpthread  main.o  libEAPI.a

将无法在基于 Debian 的发行版上链接 libpthread(Ubuntu 等)比 Debian 6 更新,因为从那时起所有库都必须按依赖顺序链接:

g++  -o secoTest main.o  libEAPI.a -lpthread

更好的是,不要使用不可移植的 -lpthread 并传递可移植的用于编译和链接的选项 -pthread。这意味着:做任何事编译/链接 Posix 线程支持是正确的

关于c++ - 将 C++ 链接到静态库; undefined reference 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49027797/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com