这是我之前的一个问题的重写。
我有一个测试应用程序,我试图与ibicuuc和libicui18n链接。 (这是大型项目的第一步。)
我将这些包含在我的项目中作为预建库
LOCAL_SHARED_LIBRARIES := libicuuc libicui18n
从git存储库中按原样编译:
https://android.googlesource.com/platform/external/icu4c/
这是clean的构建日志:
$ ndk-build
[armeabi-v7a] Prebuilt : libicui18n.so <= /usr/local/opt/android/libs/libs/armeabi-v7a/
[armeabi-v7a] Install : libicui18n.so => libs/armeabi-v7a/libicui18n.so
[armeabi-v7a] Prebuilt : libicuuc.so <= /usr/local/opt/android/libs/libs/armeabi-v7a/
[armeabi-v7a] Install : libicuuc.so => libs/armeabi-v7a/libicuuc.so
[armeabi-v7a] Compile++ thumb: main <= main.cc
[armeabi-v7a] SharedLibrary : libmain.so
[armeabi-v7a] Install : libmain.so => libs/armeabi-v7a/libmain.so
但是当应用程序运行时,它会链接到/ system中的lib,而不是我的
root@flo:/proc/27311 # grep icu maps
40665000-40756000 r-xp 00000000 b3:16 722 /system/lib/libicuuc.so
40756000-4075f000 r--p 000f0000 b3:16 722 /system/lib/libicuuc.so
4075f000-40760000 rw-p 000f9000 b3:16 722 /system/lib/libicuuc.so
4076a000-4089a000 r-xp 00000000 b3:16 721 /system/lib/libicui18n.so
4089b000-408a2000 r--p 00130000 b3:16 721 /system/lib/libicui18n.so
408a2000-408a3000 rw-p 00137000 b3:16 721 /system/lib/libicui18n.so
6fe85000-710ac000 r--s 00000000 b3:16 897 /system/usr/icu/icudt51l.dat
73454000-7467b000 r--s 00000000 b3:16 897 /system/usr/icu/icudt51l.dat
as&#34; my&#34; libs是HEAD,它们与库的第53版链接,而不是系统51,并且应用程序无法找到符号。
如何让运行时链接器从/data/data/.../lib加载我的库?
(该项目的下一阶段是构建一些不属于aosp的库,需要libicu)
如果我在java静态中使用System.loadLibrary(),似乎添加了正确的库,但似乎并没有“替换”#39; / system版本
D/dalvikvm(28077): Trying to load lib /data/app-lib/com.example.test.nativelibs-2/libicuuc.so 0x41e65670
D/dalvikvm(28077): Added shared lib /data/app-lib/com.example.test.nativelibs-2/libicuuc.so 0x41e65670
D/dalvikvm(28077): No JNI_OnLoad found in /data/app-lib/com.example.test.nativelibs-2/libicuuc.so 0x41e65670, skipping init
D/dalvikvm(28077): Trying to load lib /data/app-lib/com.example.test.nativelibs-2/libicui18n.so 0x41e65670
D/dalvikvm(28077): Added shared lib /data/app-lib/com.example.test.nativelibs-2/libicui18n.so 0x41e65670
D/dalvikvm(28077): No JNI_OnLoad found in /data/app-lib/com.example.test.nativelibs-2/libicui18n.so 0x41e65670, skipping init
D/dalvikvm(28077): Trying to load lib /data/app-lib/com.example.test.nativelibs-2/libmain.so 0x41e65670
由于
答案 0 :(得分:1)
我认为最安全/最简单的方法是重命名您自己提供的库,这应该只需要对上游源项目进行微调。 (如果你只有一个单独的库,你只需要重命名内置的.so,但当你有两个时,你需要从头开始重命名的第一个让另一个用右边引用它的soname。)
在查看System.loadLibrary
之前,可能会期望/system/lib
会在您应用的私人目录中显示,但问题可能是您的进程已经从之前加载了这些库,并且如果进程已加载了具有相同名称的库,则仿生链接器不会再次加载库。
如果已加载旧库,这也可能导致另一个问题,您的代码仍然调用旧版本的库,或者相反,系统框架调用新的(可能不兼容的)库。这是因为这些库被加载到全局命名空间中,并且在全局命名空间中只能有一个符号定义。 (对此的一个解决方案是使用符号版本控制,但仿生没有支持它。)如果遇到这种情况,你可以希望它有利于新版本的库,并且它与系统库期待旧的系统库。或者为库中的所有非静态符号添加前缀以使其唯一。