levmar是一個強大的和高效率的C/C++庫,採用Levenberg - 馬奎德(LM)優化演算法, 主要是為瞭解決非線性最小二乘問題。官網是:http://users.ics.forth.gr/~lourakis/levmar/ 在PC引用,網上有挺多的資料可以查詢到,但我想應用到Android上 ...
levmar是一個強大的和高效率的C/C++庫,採用Levenberg - 馬奎德(LM)優化演算法, 主要是為瞭解決非線性最小二乘問題。官網是:http://users.ics.forth.gr/~lourakis/levmar/ 在PC引用,網上有挺多的資料可以查詢到,但我想應用到Android上來,google了一下,找不到太多資料,只有一個國外幾年前的項目:https://github.com/3deggi/levmar-ndk 因為項目太久遠,還是採用 eclipse IDE來開發的,我嘗試搬到 Android Studio 來編譯,還是編譯不成功,最後只有重新配置eclipse 環境。最重要是,還得使用比較舊版本的NDK來編譯,我選用的NDK版本是 12b。過程中有些小錯誤,我就稍微調整了一下,然後按eclipse NDK的步驟編譯了一遍。 項目中 的 application.mk 里有一項配置: APP_ABI := armeab 這個是CPU 的指令集配置。一般我們在編譯的時候,都會相容多種CPU,於是改為: APP_ABI := all 編譯中,沒有什麼大問題,有部分警告而已,編譯成功。 編譯成功後,在libs目錄下出現了 arm64-v8a、armeabi、armeabi-v7a、mips、mips64、x86、x86_64 指令集目錄。於是,我就用真機測試一下,有部分手機通過了,有部分手機運行出錯。 各種調試之後,我發現可能是不同手機的CPU 支持的指令集不一樣,於是我通過以下代碼輸出每台手機的指令集:
String[] abis = new String[]{}; abis = Build.SUPPORTED_ABIS;得到結果如下: 魅族 note2: vivo Y51A oppo r9s: arm64-v8a, armeabi-v7a, armeabi, 當時vivo Y51A 能運行通過,而其他兩台手機運行時會崩潰。然後我猜可能 是arm64-v8a 庫出錯了。於是我把這個文件以及裡面的文件給刪了, 果然,全部手機都運行通過了。 從這裡大概知道:APP在獲取動態庫時,首先會根據CPU支持的指令集獲取第一個目錄下的動態庫,如果獲取不到,就會到下一個支持的指令集目錄獲取,以此類推。 當然這個項目算是編譯成功了,因為目前多數手機的CPU都會支持 armeabi-v7a 和 armeabi。但我們也知道很多第三方的庫都會相容 arm64-v8a 這種指令集,這個64位的指令集應該會跑得更快。 我也嘗試去重新編譯 levmar 庫,讓它相容 arm64-v8a 指令集。 我下載了其它版本的 NDK來嘗試,因為 ndk-build 命令在 r13 中預設使用 Clang,他們將在後續版本中移除 GCC。levmar 庫其實也使用到了一些 matlab 等其它語言庫,我擔心是這方面編譯出錯了。當我使用了其它版本的NDK編譯後,編譯是成功了,但是在 JNI 調用的時候就會報這樣的錯誤: 06-22 16:32:40.741: A/libc(5024): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 5024 (hvrl.levmar) 查了一下,這個錯誤的原因是,查不到相應 JNI 的實現方法,或者是 native 的代碼執行時出錯了。因為獲取不到C/C++ 的錯誤日誌,我也只能暫時放棄相容 arm64-v8a 指令集。 levmar庫是編譯成功了,是一個 levmar.a 靜態庫, 這裡 levmar 也使用到了 clapack,也編譯成了 .a靜態庫。 我已經編譯好的項目鏈接:https://pan.baidu.com/s/1pLPV4oV 歡迎大家關註我,或一起討論。