linux動態庫調用
1. 請教關於android linux動態庫.so的載入調用
有這兩種辦法:
第一種:
需求:
有時候應用修復了native層一個小BUG,應用需要更新了,但是用戶必須下載整個APK包進行安裝,而我們需要的只是替換SO
於是想,能不能載入自定義路徑下的 SO 文件呢
答案是完全沒問題:
使用系統方法:
void java.lang.System.load(String pathName)
但是有一點,pathName 路徑必須有執行許可權,意思就是說我們不能載入SD卡上的SO,因為沒有執行許可權
那也沒關系,我們復制到應用私有目錄下就OK嘛。
看碼
private void load() {
File dir = getDir("libs", Context.MODE_PRIVATE);
File soFile = new File(dir, "libTestJNI.so");
FileUtils.assetToFile(this, "libTestJNI.so", soFile);
try {
System.load(soFile.getAbsolutePath());
} catch (Exception e) {
}
}
這樣就完全OK,
我們只需要架個伺服器,每次啟動時動態監測 SO 文件有沒有更新,有則下載SO,然後載入,這樣就可以避免用戶安裝新的應用,
要知道重新安裝應用的用戶體驗是很差的,要讓用戶無感知的更新他。
第二種:
採用dlopen動態載入第三方庫,無非和system.load一樣,就是要實現指定路徑載入so的目的,這種方法升級so的話,那就的需要一個基本so,一直不變,用來調用dlopen,然後升級另一個so。
這兩種辦法都會遇到一個問題,就是不能直接載入SD卡中的so,因為sd卡沒有執行許可權,不能直接載入這種二進制文件,需要拷貝到data/data/packagename/files/ 目錄下,再次進行載入即可,拷貝也是有講究的,需要用到context.openFileOutput方法。
2. linux調用動態庫彈出界面
您想問的是動態庫的顯式調用吧。
首先打開一個新庫,並把它裝入內存。
dlopen在dlfcn.h中定義,並在dl庫中實現。
當庫被裝入後,可以把dlopen返回的句柄作為給dlsym的第一個參數,以獲得符號在庫中的地址。
3. linux對動態庫函數的調用太慢
動態庫函數在載入程序時,資料庫將被載入。但是,動態載入程序鏈接器將符號解析推遲到函數調用時間。在對共享庫的調用是通過過程鏈接表(PLT)中的一個條目間接完成的。最初,PLT中的所有條目都指向ld.so。在第一次調用函數時,ld.so查找符號的實際地址,更新PLT中的條目,並跳轉到函數。這是「懶惰」符號解析。您可以設置LD_BIND_NOW環境變數來更改此行為。除此之外,試一下不用DLL直接把函數卸載程序里的運行速度,如果仍然慢,那就是演算法的問題。
4. linuxopencv生成的靜態或動態庫怎樣在調用的時候不用安裝openvcv環境
使用cmake編譯opencv靜態鏈接庫(靜態庫),配置環境變數(動態庫和靜態庫一樣),復制dll文件。
將這三個dll分別復制到C:WindowsSystem32和C:WindowsSysWOW64目錄下。
配置包含目錄:視圖->其它窗口->屬性管理器。配置庫目錄然後配置附加依賴項。
5. 請教關於android linux動態庫.so的載入調用
1、 .so動態庫的生成
可使用gcc或者g++編譯器生成動態庫文件(此處以g++編譯器為例)
g++ -shared -fPIC -c XXX.cpp
g++ -shared -fPIC -o XXX.so XXX.o
2、 .so動態庫的動態調用介面函數說明
動態庫的調用關系可以在需要調用動態庫的程序編譯時,通過g++的-L和-l命令來指定。例如:程序test啟動時需要載入目錄/root/src/lib中的libtest_so1.so動態庫,編譯命令可照如下編寫執行:
g++ -g -o test test.cpp –L/root/src/lib –ltest_so1
(此處,我們重點講解動態庫的動態調用的方法,關於靜態的通過g++編譯命令調用的方式不作詳細講解,具體相關內容可上網查詢)
Linux下,提供專門的一組API用於完成打開動態庫,查找符號,處理出錯,關閉動態庫等功能。
下面對這些介面函數逐一介紹(調用這些介面時,需引用頭文件#include <dlfcn.h>):
1) dlopen
函數原型:void *dlopen(const char *libname,int flag);
功能描述:dlopen必須在dlerror,dlsym和dlclose之前調用,表示要將庫裝載到內存,准備使用。如果要裝載的庫依賴於其它庫,必須首先裝載依賴庫。如果dlopen操作失敗,返回NULL值;如果庫已經被裝載過,則dlopen會返回同樣的句柄。
參數中的libname一般是庫的全路徑,這樣dlopen會直接裝載該文件;如果只是指定了庫名稱,在dlopen會按照下面的機制去搜尋:
a.根據環境變數LD_LIBRARY_PATH查找
b.根據/etc/ld.so.cache查找
c.查找依次在/lib和/usr/lib目錄查找。
flag參數表示處理未定義函數的方式,可以使用RTLD_LAZY或RTLD_NOW。RTLD_LAZY表示暫時不去處理未定義函數,先把庫裝載到內存,等用到沒定義的函數再說;RTLD_NOW表示馬上檢查是否存在未定義的函數,若存在,則dlopen以失敗告終。
2) dlerror
函數原型:char *dlerror(void);
功能描述:dlerror可以獲得最近一次dlopen,dlsym或dlclose操作的錯誤信息,返回NULL表示無錯誤。dlerror在返回錯誤信息的同時,也會清除錯誤信息。
3) dlsym
函數原型:void *dlsym(void *handle,const char *symbol);
功能描述:在dlopen之後,庫被裝載到內存。dlsym可以獲得指定函數(symbol)在內存中的位置(指針)。如果找不到指定函數,則dlsym會返回NULL值。但判斷函數是否存在最好的方法是使用dlerror函數,
4) dlclose
函數原型:int dlclose(void *);
功能描述:將已經裝載的庫句柄減一,如果句柄減至零,則該庫會被卸載。如果存在析構函數,則在dlclose之後,析構函數會被調用。
3、 普通函數的調用
此處以源碼實例說明。各源碼文件關系如下:
test_so1.h和test_so1.cpp生成test_so1.so動態庫。
test_so2.h和test_so2.cpp生成test_so2.so動態庫。
test_dl.cpp生成test_dl可執行程序,test_dl通過dlopen系列等API函數,並使用函數指針以到達動態調用不同so庫中test函數的目的。
6. 如何判斷linux 動態庫調用
創建靜態庫:
ar -rcs test.a *.o
查看靜態庫:
ar -tv test.a
解壓靜態庫:
ar -x test.a
查看程序依賴的動態庫:
readelf -a xxx|grep library
如:可以看到,下面的交叉程序hello執行依賴於如下兩個動態庫。
rebi@ubuntu:~/test$ arm-none-linux-gnueabi-readelf -a hello|grep "library"
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libc.so.6]
rebi@ubuntu:~/test$
或者:readelf -l hello 即可。
nm xxx 查看符號
其中,T表示代碼段,U表示在其它地方定義,所以需要確保必須在某個.o或庫里被定義過。
7. linux c++動態庫 調用 c動態庫函數
先把.cpp編譯成動態庫,編譯方法:
g++ *.cpp –fPIC –shared –o libtest.so -libyourclib.so
其中,*.cpp表示你的.cpp文件,你可以把它們一一列出,
–fPIC:表示編譯為位置獨立的代碼,不用此選項的話編譯後的代碼是位置相關的,所以動態載入時是通過代碼拷貝的方式來滿足不同進程的需要,而不能達到真正代碼段共享的目的。
–shared:指明編譯成動態庫。
libtest.so即為生成的動態庫,以lib開頭,方便後面使用
-libyourclib.so 是你的c動態庫名
編譯好之後,就可以來編譯你的測試程序了:
gcc test.c -o test -ltest
其中,test是生成的可執行程序
-ltest表示引用生成的動態庫libtest.so
大概過程就是這樣,你先試一試
8. linux c編程調用系統的動態庫時,要使用dlopen等函數嗎
linux調用庫的方式有三種:
1.靜態鏈接庫
2.動態鏈接庫
3.動態載入庫
其中1,2都是在編程時直接調用,在鏈接時加參數-l進行鏈接
第三種需要在編程時使用dlopen等函數來獲取庫裡面函數的定義,然後進行調用.
不過對於沒有提供頭文件的動態庫,只能dlopen等函數來調用
9. 如何讓自己的動態鏈接庫文件能夠在linux下被調用
如何讓自己的動態鏈接庫文件能夠在linux下被調用
VxWorks
安裝的DVD有很多自己的動態鏈接庫文件,在啟動一些服務的時候需要調用這些動態鏈接庫文件,否則不能啟動一些功能,report:找不到相關的庫文件。
解決的方法可以有多種:
1.
直接創建軟連接的方式,將某動態鏈接庫文件鏈接到
/lib
或者/usr/lib
下。
ln
-s
`pwd`/xxx.so
/lib/xxx.so
這種方式適合少數固定不變動態鏈接庫文件的調用,但如果文件很多,或者這些文件也是經常存在更新的,這么多比較繁瑣。
2.
如果直接把動態鏈接庫文件所在的路徑直接加到系統查找庫的路徑下,這里有兩種方式:
1)
更改/etc/ld.so.conf,
加入自己的動態鏈接庫路徑,好像需要更新/etc/ld.so.cache;
該方法應該可用,沒有嘗試過。
2)
更改環境變數LD_LIBRARY_PATH,把自己的動態鏈接庫路徑,加入到該環境變數中。
export
LD_LIBRARY_PATH=/Jenkins/workspace/Mefa_Nightly_regression_Job02/MAIN/mefa_platform/logs_1st_round/mefaImage/simulatorTools:$LD_LIBRARY_PATH
在該環境變數中的動態鏈接庫文件會比系統中/lib
或者
/usr/lib
更早調用。
linux重啟之後,該環境變數會失效;
這種方式更適合自動化的測試的需要。