前幾天調試安卓下某個應用程式的加密功能,需要依賴openssl庫,由于編譯制定了連接配接libssl.so.xxx,但是沒有指定完整路徑,結果發現這個應用程式沒有起來,通過調試發現,程式起來的時候提示找不到SSL_xxx函數,但是通過arm-linux-androideabi-nm libssl.so.1.x.x | grep SSL_xxx
000390bc T SSL_xxx,發現動态庫裡面有這個SSL_xxx函數,然而懷疑是不是安卓裝置裡面的libssl.so.1.x.x動态庫,跟應用程式實際編譯連結時的libssl.so.1.x.x動态庫不是同一個動态庫,然後想到通過md5計算下這兩個動态庫是不是同一個動态庫,md5sum libssl.so.1.x.x後,發現兩邊的這個動态庫的md5值是一樣的,說明動态庫是一樣的,即動态庫沒有問題。
檢視安卓的動态庫目錄下,有兩個libssl打頭的動态庫,其中一個就是我們應用程式需要用到的libssl.so.1.x.x,結合調試應用程式啟動失敗的列印資訊,雖然應用列印提示連結的動态庫是libssl.so.1.x.x,但是後面又提示找不到 SSL_xxx函數,懷疑程式實際運作時實際連結的動态庫用的是libssl打頭的另外一個動态庫,為了驗證這種猜想,重新修改了Makefile,編譯連接配接時顯示指定了openssl庫的路徑及連結庫,重新編譯後,應用程式替換到安卓裝置上後,發現可以正常運作起來,也證明了自己的猜想。
做過跨平台程式的同學,應該清楚,Windows平台下編譯程式,連結動态庫時,需要顯示指定所連結動态庫的路徑;而Linux平台下則不需要,連結時系統會自動查找(需要注意一點,當系統下有不同版本的某個動态庫,比如:依賴的A庫依賴動态庫libxxx.so.0,依賴的B庫依賴動态庫libxxx.so.1,這時需要注意應用程式連結A庫和B庫的順序,那個在前那個在後,編譯時可能需要調整連結庫的順序,否則可能會遇到編譯失敗的問題);安卓環境感覺是介于Windows和Linux之間,編譯連結程式時,需要注意下,可能遇到筆者的情形。