2017-04-06 123 views
32

我發現了一些類似的問題(例如this,thatthis),但沒有一個幫助我解決了我的問題。我有一個* .so文件(從gnss-sdr核心),作爲表示由:g ++ undefined reference雖然符號出現在* .so文件中

$nm libgnss_system_parameters_dyn.so | c++filt |grep Gps_Eph 

包含符號Gps_Ephemeris::Gps_Ephemeris(),這應該是一個構造函數。

我已經寫了一些最少的代碼:

#include <iostream> 
#include <core/system_parameters/gps_ephemeris.h> 

int main(int argc,const char* argv[]) 
{ 
    Gps_Ephemeris ge; 
    return 0; 
} 

我與編譯:

g++ main.cpp -std=c++0x -I some_include_path -L some_lib_path -l gnss_system_parameters_dyn` 

然後連接器抱怨:

/tmp/ccHCvldG.o: In function `main': 
main.cpp:(.text+0x33): undefined reference to `Gps_Ephemeris::Gps_Ephemeris()' 
collect2: error: ld returned 1 exit status 

我也試過cmake的,但它生成的行類似於(它只是添加了-rdynamic之前),並且它仍然生成完全相同的鏈接器錯誤。

注意的是,庫和我的最少的代碼被用相同的編譯器編譯的(G ++ - 5)中,用完全相同的標誌和相同的C++ 0x標準。


尋址由馬克西姆Egorushkin,行答案:

nm --demangle --defined-only --extern-only libgnss_system_parameters.so |grep Gps_Eph 

不輸出任何東西。然而,該符號在靜態庫(的* .A庫)定義:

00000000000006b0 T Gps_Ephemeris::Gps_Ephemeris() 
00000000000006b0 T Gps_Ephemeris::Gps_Ephemeris() 

明知兩者都由cmake的生成,通過以下方式:

add_library(lib_name SHARED ${sources_etc}) #for the *.so 
add_library(lib_name_2 ${sources_etc}) #for the *.a 

這些庫中包含/定義的符號應該沒有區別,對吧?我沒有注意到在add_librarycmake的的文檔任何東西。我錯過了明顯的東西嗎?

+3

你說輸出_包含符號'Gps_Ephemeris :: Gps_Ephermeris()'_,但不顯示實際的輸出。這是相關的,並且會很有用。此外,您顯然沒有將該符號複製並粘貼到問題中,因爲您拼錯了它。我對這種書面摘要不信任,因爲如果你是一個可靠的評判者,你可能不會問這個問題。 – Useless

+0

感謝您的注意,我解決了它。我主要是做高級計算機視覺,所以是的,我覺得沒有資格判斷要排除什麼。我會盡快發佈輸出。 – Ash

+0

沒有看源代碼,很難說明爲什麼.so和.a從相同的源構建出口不同的符號。有條件編譯可能涉及。 –

回答

17

的迂腐正確的方法來檢查一個.so出口的標誌是nm --demangle --dynamic --defined-only --extern-only <lib.so> | grep <symbol>

沒有--defined-only您的命令還顯示undefined符號。

沒有--extern-only它也顯示符號與內部鏈接這是不可用於鏈接。

它看起來像你需要鏈接另一個庫,因爲Gps_Ephemeris::Gps_Ephermeris()不鏈接libgnss_system_parameters_dyn.so解決。開始的一個好方法是圖書館的文件和例子。

+0

非常感謝!你是對的。但是,這些符號存在於(等效的)靜態庫中。我在最後用一些信息更新了這個問題。你可以看一下嗎? – Ash

1

我在過去發現,這種類型的錯誤是缺乏適當的extern "C" { ... }在include文件包圍引起的。

+1

你能詳細說明'extern「C」'鏈接如何處理構造函數嗎? –

+0

它沒有。它們不是C的一部分,而是C++的一部分。 – Nicole