簡體   English   中英

如何找到庫以使用 dlopen 動態加載它們

[英]How can I find libraries to load them dynamically with dlopen

在我正在進行的項目中,我們提供了動態加載附加功能的可能性。 為此,我們使用 dlopen。

為了找到這個庫,我們有一些我們稱之為模塊路徑的東西。 我們有一個默認路徑,共享庫所在的位置(其中很多已發貨)。

目前我們有兩個默認路徑:我們首先在構建目錄中查找共享庫,然后在安裝目錄中查找。 這是因為它也應該可以在不安裝的情況下運行應用程序(因此在這種情況下,它需要首先在構建目錄中查找)。

現在問題來了,如果用戶從源代碼構建應用程序並使用 make install 安裝它,則默認情況下會加載她構建目錄中的庫。 這將導致崩潰。 因此,它僅在用戶隨后刪除或重命名構建目錄時才有效。

沒有問題:是否有一個技巧(通過 C++ 或構建系統)來知道應用程序是否已安裝。 問題是,該功能是在共享庫中實現的,搜索模塊的實現方式也必須適用於鏈接到我們庫的其他應用程序(因此我們不能依賴可執行文件的路徑)。 我們使用 CMake 作為構建系統。

為了使情況更加困難,該解決方案必須適用於 Windows、Linux 和 Mac OS X。

編輯:

我進一步調查,問題更復雜。 這是這種情況:

  • 有一個小的可執行文件
  • 此外,還有一個“主”庫 main.so
  • 然后有一個動態加載的庫 lib.so
  • lib.so 鏈接到 main.so

問題是,lib.so 在其 rpath 的構建目錄中具有 main.so 的絕對路徑。 感謝@MSalters 的提示,我現在能夠進行破解以確保加載正確版本的 lib.so(安裝目錄中的那個),但是由於它在 rpath 中有構建路徑,因此它加載了錯誤的 main .so(所以實際上在 memory 中有兩個 main.so 副本 - 這搞砸了)。

有沒有辦法從庫中刪除對構建路徑的引用? 我嘗試了與 rpath 相關的 cmake 的所有選項,但均未成功

你不能檢查可執行文件本身在哪里嗎? 如果它在構建目錄中,請使用構建庫——如果它在安裝中,請使用 install?

getcwd()在所有這些平台上都有等價物,但它可能不是你想要的——這取決於你如何運行可執行文件。

我認為,要獲得進程的位置是系統特定的,但包裝它應該不會太難。

安裝的版本不應該在 rpath 中有構建目錄。

您可能需要進行兩次鏈接(一次用於構建版本,一次用於安裝版本)。 通常,在 *nix 系統上,已安裝的二進制文件有一些 static 路徑,它會在其中嘗試查找插件。 您可以定義一些環境變量(或命令行參數)來重載它以執行構建(並使用包裝腳本在構建環境中設置它)。

檢查某些項目(例如 Firefox)如何解決它。

我對 windows 系統了解不多,但我認為這樣做的標准方法是在與可執行文件相同的目錄中搜索插件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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