2011-09-11 58 views
1

我正在研究一個有'核心'和多個插件的應用程序。我在Linux上使用Qt,並使用Qt的插件加載器系統。插件被創建爲共享對象文件(* .so)並動態加載。如果我使用插件鏈接到庫,並且該庫鏈接到其他庫,我經常會從應用程序中收到「未定義符號」錯誤。要解決它,我需要插件C++爲什麼這種特定情況會導致符號鏈接錯誤?

插件鏈接鏈接到其他庫,以及...以力霸

力霸鏈接到LibB,的LibC

力霸被編譯爲靜態的。當我嘗試加載插件,我會得到一個未定義的符號錯誤,就像這樣:

unable to load shared library 'myPluginName.so': 
myPluginName.so: undefined symbol: _ZN3BlahBlahD2Ev 

爲了解決這個問題,我可以使用FILT到unmangle符號名稱,找出哪些庫在符號所屬(比方說LibB),然後編譯,如:

插件鏈接,力霸,LibB

力霸鏈接到LibB,的LibC

我不知道爲何出現錯誤。如果LibA鏈接到LibB和LibC,Plugin爲什麼還必須「瞭解」LibB?爲什麼在所有情況下都不會出現這種錯誤(即沒有與使用LibC的未定義符號相關的錯誤)?

我會很感激任何輸入。

-kf

+2

如果將LibA構建爲靜態庫,它不應該有任何動態依賴關係,對吧? (如果我在這裏感到困惑,請糾正我)無論如何,如果你在Linux上,你應該能夠在你的plugin.so上運行'ldd',看看是否有任何未解決的庫引用...如果不是,還有其他事情正在發生。 –

回答

3

你要記住,靜態庫只是一起打包成一個單一的文件對象文件的集合。如果你的插件需要LibA,並且LibA需要LibB和LibC,那麼當你連接你的插件時,你必須告訴鏈接器LibA,LibB和LibC在哪裏。

如果你使用動態庫,這將是一個不同的故事。 .so已經鏈接,所以它的所有引用都已經解決了。如果LibA是一個動態鏈接庫,那麼您的插件只需要鏈接到LibA.so,因爲鏈接步驟已經發生,以便將LibA綁定到它自己的依賴項。

1

如果靜態庫包含來自其靜態依賴關係的符號,則會由於多重定義的符號而導致各種令人討厭的警告和錯誤。

考慮這樣的情況:

  • 力霸取決於libB)和libc(
  • => libB取決於LIBD
  • =>的libC取決於LIBD

至少,從我的經驗MSVS世界。

+0

經過幾次閱讀之後,爲什麼我需要像這樣多次鏈接,這讓我感到非常緊張。謝謝 :) – kfl

相關問題