2016-11-18 124 views
1

有一組插件的一個應用程序,所有鏈接到一個共同的基礎庫。基礎庫定義了一個單例,它維護着每個插件中所有對象構造函數的列表。我如何創建共享庫的具體實例單

在windows上,我可以創建這個基本庫作爲一個靜態庫,因此單例的副本放置在每個插件中。 但是在Linux上我有一點相反的問題as this fellow.

我已經試過到目前爲止以下內容:

  • 建基地作爲共享庫(按照原作者)
  • 建基地作爲靜態與-fPIC
  • 建基地與-fPIC爲靜態,明確的CMake刪除-rdynamic

我真的想保持程序結構與現在一樣,通過讓singleton定義駐留在基本庫內部,讓每個插件擁有自己的實例。我已經嘗試將定義移到每個插件中,但我真的很想避免這種情況。 本質上我想重現他認爲的一個錯誤。但是他完全定義在一個頭文件,它是有道理的,我認爲每個插件會再有它自己的類的實例化他的單,我就另一方面也要編入基礎庫單身的定義。

回答

1

最好的解決方案是在Windows上做同樣的事情:將基礎庫編譯爲歸檔(靜態)庫並將其鏈接到每個插件中。 (這需要使用-fPIC編譯基本庫。)

原因不起作用:您沒有控制從插件導出的函數。

在Windows上,除非您明確指出插件的功能DLLEXPORT,否則它仍然是內部的。在Linux中,默認是相反的,並且當兩個共享庫導出同一符號,第一個加載獲勝。

所以,這裏是你需要做什麼:

  1. 編譯基礎庫-fPIC -fvisibility=hidden
  2. 對於您想從插件出口,增加__attribute__((visibility("default")))的特定功能。

完成此操作後,運行nm -D new-plugin.so並與nm -D old-plugin.so進行比較。您應該看到,舊的插件出口的一切,以及新的插件出口功能標記要出口。

另一種替代方法是使用linker script控制符號可見。

+0

另一個機會是[使用可見性編譯指示](https://gcc.gnu.org/onlinedocs/gcc/Visibility-Pragmas.html)。 – yugr

+0

謝謝你的迴應,我會在接下來的幾天裏進行測試,並確認這是否適合我的工作。 –

+0

經過測試和驗證,這適用於我想要做的事。非常感謝。 –