簡體   English   中英

在運行時具有不同名稱的動態加載庫

[英]Dynamic loading library with different name at runtime

是否可以構建一個依賴於另一個共享庫(在我的情況下為 RocksDB - librocksdb.so )的共享庫(使用 g++),但其運行時的文件名不同? (例如librocksdb1234.so )。 如果是這樣,如何做到這一點?

更多背景

  1. 我正在為 RocksDB (C++) 實現一個自定義壓縮過濾器,我打算通過 JNI 在我的 Java 應用程序中使用它。

  2. 在 Java 中使用 RocksDB 時,我需要首先調用RocksDB.loadLibrary() ,它將加載 RocksDB 庫。 RocksDB JNI jar 帶有多個 RocksDB 共享對象(.so 文件),每個架構一個。 當我調用此方法時,它將 select jar 中正確的共享 object 文件,將其復制到臨時文件夾,然后使用System.load(...)加載。 復制的共享 object 文件是使用隨機后綴創建的

  3. 對於自定義壓縮過濾器的開發,我首先安裝了 RocksDB 頭文件(這只是調用 RocksDB 項目中的 Makefile 任務,將頭文件復制到/usr/local/include/rocksdb ),並將 RocksDB 構建為共享庫並將其安裝在/usr/local/lib中(同樣,這只是對項目中已經存在的 Makefile 任務的調用)。

  4. 要使用自定義壓縮過濾器構建共享庫,我使用 g++ 如下(用於鏈接): g++ -shared -fPI -Wl,--no-undefined <list-of-object-files> -o libcustom.so -lrocksdb (安裝的 RocksDB 共享庫名為librocksdb.so )。

  5. 當我嘗試在我的 Java 應用程序上使用自定義壓縮過濾器加載我的共享庫時,它會按預期成功加載(只要存在librocksdb.so )。

  6. 但是由於 RocksDB JNI 已經附帶了 RocksDB 共享 object 文件,我想要的只是使用這些共享對象,而不是我為開發目的安裝的librocksdb.so 所以,我基本上只是刪除librocksdb.so並在我的 Java 應用程序中添加對RocksDB.loadLibrary()的調用。 執行此操作后,由於librocksdb.so.6: cannot open shared object file: No such file or directory ,我將無法加載我的共享庫。

  7. 我驗證了使用lsof -p <pid>正確加載了 RocksDB 共享 object(來自 jar)。

  8. 據我了解,發生這種情況是因為我與自定義壓縮過濾器共享的 object 將在其 header 中有一個條目,該條目定義了對名為rocksdb的庫的依賴(使用objdump -x...確認)。 但是由於RocksDB.loadLibrary()加載的 RocksDB 共享 object 有一個隨機名稱,它不會匹配所需的依賴項。

Dynamic Section:
  NEEDED               librocksdb.so.6
...

附帶問題在第 8 點中。我假設動態加載將基於共享 object 的文件名。 這是一個正確的假設嗎? 或者動態加載是否基於 SONAME? (我注意到 RocksDB JNI jar 中的共享對象沒有定義 SONAME)。

要使用自定義壓縮過濾器構建共享庫,我使用 g++ 如下

請注意,如果您保證庫所需的librocksdb.so.6中的所有符號在加載庫之前已經存在,那么您根本不必將共享庫與librocksdb鏈接。 只需從鏈接命令行中刪除-lrocksdb ,它就會正常加載。

暫無
暫無

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

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