簡體   English   中英

將C ++鏈接到靜態庫; 未定義的參考錯誤

[英]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所建議的,這是不帶--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鏈接,因此它將發出對聲明的符號的無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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM