[英]"undefined reference to" errors when linking static C library with C++ code
[英]Linking C++ to static library; undefined reference errors
我正在嘗試將小型C ++測試程序main.o
到第三方靜態庫,但遇到一些無法解釋的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
這是未定義引用的原因嗎? 我該如何解決? 不確定接下來要看的地方...
(我不能修改第3方庫,但有頭文件。)
編輯
正如lisyarus所建議的,這是不帶--demangle
的nm
。 實際上,符號是不同的。 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鏈接,因此它將發出對聲明的符號的無libEAPI
引用:
main.cpp
...
extern "C" {
#include "EAPI.h" // or whatever
}
...
順便說一句,此命令行:
g++ -o secoTest -lpthread main.o libEAPI.a
比起Debian 6,將無法在基於Debian的發行版(Ubuntu等)上鏈接libpthread
,因為從那時起,所有庫都必須按照依賴關系順序進行鏈接:
g++ -o secoTest main.o libEAPI.a -lpthread
更好的是,不要使用不可移植的-lpthread
並通過可移植選項-pthread
進行編譯和鏈接。 這意味着: 在Posix Threads支持下進行正確的編譯/鏈接
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.