我有一個依賴于 OpenCV 的原生 Android、SDK 樣式庫。
為了避免用戶使用庫和他們自己使用 OpenCV 時的沖突,我想將 OpenCV 靜態編譯到我的庫中并隱藏它的符號。
我靜態編譯了 OpenCV(3.4.13world模塊)并使用它,以及它在我的庫中的第 3 方庫。
當我嘗試使用我的庫時,它會引發例外,即使用戶捕獲到例外,也會SIGABRT導致應用程式終止。
這是來自 logcat 的堆疊跟蹤
A/libc: Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 24115 (.test), pid 24115 (.test)
...
A/DEBUG: backtrace:
A/DEBUG: #00 pc 0000000000051948 /apex/com.android.runtime/lib64/bionic/libc.so (abort 168) (BuildId: 931371c1098ffd5adc489b9ff4da8e82)
A/DEBUG: #01 pc 00000000000b2ba0 /data/app/~~gc4ZOfzcr7C0hRfmsieCtQ==/com.example.test-sx2ESCfGCsi3lXPZWnk9nA==/base.apk!libc _shared.so (BuildId: ece72a2ebc3774a1be9fd21271258acd3bcdfaa7)
A/DEBUG: #02 pc 00000000000aec8c /data/app/~~gc4ZOfzcr7C0hRfmsieCtQ==/com.example.test-sx2ESCfGCsi3lXPZWnk9nA==/base.apk!libc _shared.so (__gxx_personality_v0 348) (BuildId: ece72a2ebc3774a1be9fd21271258acd3bcdfaa7)
A/DEBUG: #03 pc 00000000004dd2dc /data/app/~~gc4ZOfzcr7C0hRfmsieCtQ==/com.example.test-sx2ESCfGCsi3lXPZWnk9nA==/base.apk!libmylib.so (BuildId: 790f2880373cb985055ab9b7b2efc48b1afb82fd)
A/DEBUG: #04 pc 00000000004dd7e4 /data/app/~~gc4ZOfzcr7C0hRfmsieCtQ==/com.example.test-sx2ESCfGCsi3lXPZWnk9nA==/base.apk!libmylib.so (BuildId: 790f2880373cb985055ab9b7b2efc48b1afb82fd)
A/DEBUG: #05 pc 0000000000170600 /data/app/~~gc4ZOfzcr7C0hRfmsieCtQ==/com.example.test-sx2ESCfGCsi3lXPZWnk9nA==/base.apk!libmylib.so (mylib::TestClass::TestClass(char const*, char const*) 908) (BuildId: 790f2880373cb985055ab9b7b2efc48b1afb82fd)
A/DEBUG: #06 pc 000000000000c5d0 /data/app/~~gc4ZOfzcr7C0hRfmsieCtQ==/com.example.test-sx2ESCfGCsi3lXPZWnk9nA==/base.apk!libJnilibrary.so (BuildId: 7f3605ea8cb95dc87864e3df22f6b77b46c2e592)
A/DEBUG: #07 pc 000000000000c3b8 /data/app/~~gc4ZOfzcr7C0hRfmsieCtQ==/com.example.test-sx2ESCfGCsi3lXPZWnk9nA==/base.apk!libJnilibrary.so (BuildId: 7f3605ea8cb95dc87864e3df22f6b77b46c2e592)
A/DEBUG: #08 pc 000000000000c308 /data/app/~~gc4ZOfzcr7C0hRfmsieCtQ==/com.example.test-sx2ESCfGCsi3lXPZWnk9nA==/base.apk!libJnilibrary.so (Java_com_example_lib_Engine_cxxInit 56) (BuildId: 7f3605ea8cb95dc87864e3df22f6b77b46c2e592)
A/DEBUG: #09 pc 00000000002d7644 /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline 148) (BuildId: 2b417e2566f5eb686666666b6ee952ea)
(如果 JNI 庫使用c _static,也會發生這種情況,但在這種情況下__gxx_personality_v0,它上面的 and 1 來自libJnilibrary.so)
如果我將 OpenCV 編譯為共享庫并將我的庫鏈接到它,那么一切正常。
我以前在我的庫中遇到過例外問題,請參閱我提出的這個問題。我通過使用c _staticSTL 編譯所有內容來解決它。問題看起來與此類似,確實我錯過了key function,但即使添加了它,問題仍然存在。
我查看了使用的符號,llvm-readelf -CWs并注意到當動態鏈接 OpenCV 時,除了 OpenCV 符號外,輸出還包含一些靜態使用 OpenCV 時不存在的 ndk 和 cxxabi 符號。我不知道它是否相關,但例如
110: 0000000000000000 0 FUNC GLOBAL DEFAULT UND std::uncaught_exception()
...
201: 0000000000000000 0 OBJECT GLOBAL DEFAULT UND vtable for __cxxabiv1::__vmi_class_type_info
...
231: 0000000000000000 0 FUNC GLOBAL DEFAULT UND std::__ndk1::to_string(unsigned int)
(使用靜態構建的 OpenCV 時,所有這些都缺失)
我正在使用 ndk 版本21e(我目前不能使用更高版本,因為另一個庫使用Bazel并且它目前最多支持 21 個)
OpenCV 使用以下標志構建
cmake -DCMAKE_BUILD_TYPE=Release -DINSTALL_ANDROID_EXAMPLES=OFF -DANDROID_EXAMPLES_WITH_LIBS=OFF -DANDROID_ABI="arm64-v8a"
-DBUILD_EXAMPLES=OFF -DBUILD_DOCS=OFF -DWITH_OPENCL=OFF -DBUILD_ANDROID_PROJECTS=OFF -DBUILD_ANDROID_EXAMPLES=OFF -DANDROID_ARM_NEON=1
-DANDROID_STL=c _static -DANDROID_PLATFORM=android-21 -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake"
-DBUILD_SHARED_LIBS=OFF -DBUILD_FAT_JAVA_LIB=OFF -DBUILD_JAVA=OFF -DINSTALL_CREATE_DISTRIB=ON -DINSTALL_ANDROID_EXAMPLES=OFF -DBUILD_opencv_objdetect=OFF
-DBUILD_opencv_video=ON -DBUILD_opencv_videoio=ON -DBUILD_opencv_features2d=ON -DBUILD_opencv_flann=OFF -DBUILD_opencv_highgui=ON -DBUILD_opencv_ml=OFF
-DBUILD_opencv_photo=OFF -DBUILD_opencv_python=OFF -DBUILD_opencv_shape=OFF -DBUILD_opencv_stitching=OFF -DBUILD_opencv_superres=OFF -DBUILD_opencv_ts=OFF
-DBUILD_opencv_videostab=OFF -DBUILD_ANDROID_PROJECTS=OFF -DBUILD_opencv_world=ON -DBUILD_opencv_dnn=OFF -DBUILD_opencv_core=ON -DBUILD_opencv_imgcodecs=ON
-DBUILD_opencv_imgproc=ON -DBUILD_opencv_calib3d=ON -GNinja -DCMAKE_INSTALL_PREFIX=../install -DBUILD_ZLIB=1 -DWITH_PROTOBUF=OFF -DWITH_QUIRC=OFF ..
我的庫是使用帶有這些 CMake 標志的 Gradle 和 Android Studio 編譯的
externalNativeBuild {
cmake {
cppFlags "-std=c 17 -static-openmp -fopenmp -fexceptions -frtti -Wno-unused-command-line-argument -Wl,-s"
cppFlags "-Wl,--exclude-libs,libc _static.a -Wl,--exclude-libs,libc abi.a"
arguments "-DANDROID_STL=c _static", "-DANDROID_ARM_NEON=TRUE"
}
}
uj5u.com熱心網友回復:
這個問題最終與第 3 方或類似的事情無關。
我使用的是 NDK 版本r21e。升級 NDK 以r24解決此問題。
似乎當OpenCV作為共享物件鏈接時,它通過匯入或包含一些丟失/有問題的符號來掩蓋實際的 NDK 錯誤,當我們停止使用它時,出現了錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/497357.html
