我有三樣東西:開源應用程序(我們稱之爲APP), 封閉源代碼的共享庫(姑且稱之爲OPENGL) 和開源插件OPENGL(讓我們稱之爲PLUGIN)[也是共享庫]。
操作系統:Linux。
需要在APP和PLUGIN之間共享數據, 這樣APP與PLUGIN連接,當我運行它時, 系統會自動加載它。
之後,APP調用屬於OPENGL的eglInitialize, ,之後該函數再次加載PLUGIN。
之後我在APP內存中有兩個PLUGIN副本。
我知道,因爲PLUGIN有全局數據,並且經過調試 我看到有兩個全局數據副本。
所以問我如何解決這個問題? 我想要一個由APP和OPENGL使用的PLUGIN實例。 我無法更改OPENGL庫。dlopen的和隱性的庫加載:同一庫的兩個副本
回答
我懷疑OPENGL正在加載帶有RTLD_LOCAL
標誌的PLUGIN。這個 通常是你在加載插件時想要的,所以多個插件不會衝突。
我們在Java下加載代碼時遇到了類似的問題:我們會加載一個 左右的不同模塊,並且它們不能與另一個 進行通信。我們的解決方案可能適用於您:我們爲插件編寫了一個 包裝器,並告訴Java包裝器是插件。 然後,該插件使用dlopen
與RTLD_GLOBAL
加載其他每個共享對象。這在插件之間起作用。但我不確定它 將允許插件返回主界面,但是(但我認爲它應該是 )。和IIRC,當鏈接主要的 其符號可用時,您需要特殊選項。我認爲Linux會將主要的 中的符號看作是否已經裝載了RTLD_LOCAL
。 (也許 --export-dynamic
?這是一段時間,因爲我不得不這樣做,我 不記得確切。)
它顯然很大程度上取決於庫的功能,但一般情況下應該有一些解決方案。
首先請注意,通常如果一個名稱相同的共享庫被加載多次,它將繼續使用相同的庫。這種主要適用於通過標準加載/鏈接機制加載。如果庫自己調用dlopen
,它仍然可以獲得相同的庫,但它取決於標記dlopen
。嘗試閱讀dlopen上的文檔,瞭解它是如何工作的以及如何操作它。
您還可以嘗試在鏈接器命令中早先定位PLUGIN,以便它首先被加載,從而可以避免稍後再加載一次。如果你必須動態加載插件,這顯然無濟於事。您還可以檢查LD_PRELOAD
是否可以解決鏈接順序。
作爲最後的手段,您可能不得不求助於使用LD_LIBARY_PATH
並將真實接口庫放入其中。這隻會將呼叫傳遞給真實的呼叫,但會攔截重複的負載並將其分流到之前的負載。
這只是一個需要考慮的方向。您的實際答案將取決於您的代碼以及其他共享庫的功能。在進入其他選項之前,請首先調查鏈接器加載順序,因爲它是最容易檢查的,然後是dlopen標誌。
- 1. JNA加載同一個庫的多個副本
- 2. 加載共享庫的多個副本
- 3. 同步兩個mongodb數據庫副本
- 4. 如果hibernate從數據庫加載兩次,它會加載兩個相同實例的單獨副本嗎?
- 5. 同一個庫的兩個版本
- 6. 相同靜態庫的多個副本?
- 7. 由兩個存儲庫組成的一個工作副本
- 8. SVN:如何簽出同一存儲庫的兩個本地副本
- 9. 共享庫(dlopen)和庫靜態指針的線程安全性
- 10. 在JVM中並行加載同一個庫的不同版本
- 11. 在同一進程中加載一組DLL的多個副本
- 12. 加載本機庫兩次
- 13. 如何添加現有庫的副本加載項生成器
- 14. SVN:如何工作副本後傾銷和加載到另一個倉庫
- 15. 加載共享庫的兩個實例
- 16. 沒有RTLD_GLOBAL的typeinfo,共享庫和dlopen()
- 17. 從兩個版本的庫加載類取決於Android版本
- 18. 將代碼庫的不同副本添加到現有的git存儲庫
- 19. 用dlopen加載的共享庫是否自動關閉?
- 20. 的dlopen()不能加載庫:開羅/開羅2
- 21. 枚舉通過dlopen加載的共享庫(RTLD_GLOBAL)
- 22. 加載包含相同符號的兩個本地庫時的內存問題
- 23. 有兩個「配置」的同一個基本倉庫時的倉庫結構?
- 24. 從同一類的兩個不同模板副本繼承時重載
- 25. 加載兩個不同版本的DLL
- 26. dlopen的具有兩個共享庫,導出符號
- 27. 瀏覽同一存儲庫的兩個不同版本
- 28. 在同一個數據庫中創建一個表的副本DB2
- 29. 調用加載另一個本機庫的本地庫時的JNI問題
- 30. 使用同一個庫的兩個版本
我想你幾乎接近真正的解決方案。問題出在RTLD_LOCAL。 OPENGL爲PLUGIN.so.1調用dlopen。 APP與PLUGIN.so鏈接。在scp之後,PLUGIN.so成爲不是軟鏈接到PLUGIN.so.1,而是真正的文件。所以我在進程的地址空間中有兩個文件PLUGIN.so和PLUGIN.so.1。 – fghj