在 Android 中,如何强制本机代码使用我的共享库版本,而不是系统的?
In Android, how to force the native code to use my version of a shared library, instead of the system's?
Android 已经有了 PCRE 共享库(“/system/lib/libpcre.so”),但它是在没有 Unicode 支持的情况下编译的,所以我为 [=16= 构建了自己的 PCRE 版本].我的本机代码链接到 PCRE 共享库。但是,当我 运行 我的应用程序时,它使用系统版本的 PCRE,而不是我构建的版本,即使我的 APK 确实包含我的 PCRE 版本。我如何让它使用我的 PCRE 版本而不是系统的?通常在 Linux 我使用 "LD_LIBRARY_PATH" 或 "RPATH",但在 Android 我不知道如何使用它们,如果可能的话。
我认为唯一的方法是重命名库(例如 libpcre_myapp)。
请注意,仅重命名文件可能还不够,但要更改 SO_NAME ELF 属性。
您可以在加载主库之前load("your-path-to-lib")
。使用 this API 您可以在任意位置加载本机库。但最简单的方法是依赖构建和安装程序的默认行为,这将打包本机库(名为 lib
something.so
) 它在 libs/<ABI>
文件夹中找到的,放入 APK 文件中,并将与目标匹配的 ABI 变体解压到
getContext().getApplicationInfo().nativeLibraryDir
(这是在 API 级别 9 中添加的)
如果库是预加载的,则您无法将库与系统库并排放置,因为 bug 包含旧版本的 Android。不过,您可能会成功手动卸载它,使用 dlclose()
:
handle = dlopen("<libname>", RTLD_NOLOAD);
dlclose(handle);
dlclose(handle); // twice, because dlopen() increments ref count
您可能会在一个单独的小 dlclose_helper.so
中进行这些操作。在加载主库之前加载这个辅助加载,它需要 <libname>
.
的私有版本
为 API 级别 23 引入了一个修复程序,使我们最终可以同时加载 dir1/libx.so
和 dir2/libx.so
(参见 official doc)。
请注意,对于 API 级别 24,还引入了 new restrictions 以限制对系统库的访问(您只能加载列入白名单的库)。
Android 已经有了 PCRE 共享库(“/system/lib/libpcre.so”),但它是在没有 Unicode 支持的情况下编译的,所以我为 [=16= 构建了自己的 PCRE 版本].我的本机代码链接到 PCRE 共享库。但是,当我 运行 我的应用程序时,它使用系统版本的 PCRE,而不是我构建的版本,即使我的 APK 确实包含我的 PCRE 版本。我如何让它使用我的 PCRE 版本而不是系统的?通常在 Linux 我使用 "LD_LIBRARY_PATH" 或 "RPATH",但在 Android 我不知道如何使用它们,如果可能的话。
我认为唯一的方法是重命名库(例如 libpcre_myapp)。
请注意,仅重命名文件可能还不够,但要更改 SO_NAME ELF 属性。
您可以在加载主库之前load("your-path-to-lib")
。使用 this API 您可以在任意位置加载本机库。但最简单的方法是依赖构建和安装程序的默认行为,这将打包本机库(名为 lib
something.so
) 它在 libs/<ABI>
文件夹中找到的,放入 APK 文件中,并将与目标匹配的 ABI 变体解压到
getContext().getApplicationInfo().nativeLibraryDir
(这是在 API 级别 9 中添加的)
如果库是预加载的,则您无法将库与系统库并排放置,因为 bug 包含旧版本的 Android。不过,您可能会成功手动卸载它,使用 dlclose()
:
handle = dlopen("<libname>", RTLD_NOLOAD);
dlclose(handle);
dlclose(handle); // twice, because dlopen() increments ref count
您可能会在一个单独的小 dlclose_helper.so
中进行这些操作。在加载主库之前加载这个辅助加载,它需要 <libname>
.
为 API 级别 23 引入了一个修复程序,使我们最终可以同时加载 dir1/libx.so
和 dir2/libx.so
(参见 official doc)。
请注意,对于 API 级别 24,还引入了 new restrictions 以限制对系统库的访问(您只能加载列入白名单的库)。