Android 上有时会忽略 LD_LIBRARY_PATH

2024-01-25

我有一个 Android 应用程序,它会生成许多与我随包分发的库动态链接的本机可执行文件。 为了启动这些二进制文件,我使用 LD_LIBRARY_PATH 环境变量让它们知道从中加载库的位置,但在某些设备上这根本不起作用,LD_LIBRARY_PATH 已正确更新,但二进制文件无论如何都找不到库。 这不是我可以复制的东西,因为在我的两台设备(带有库存 ROM 的 Galaxy Nexus 和 Nexus 7)上它工作得很好。

我尝试了很多方法,例如我产卵:

LD_LIBRARY_PATH=/my/package/custom/libs:$LD_LIBRARY_PATH && cd /binary/directory && ./binary

And :

    String[] envp = { "LD_LIBRARY_PATH=" + libPath + ":$LD_LIBRARY_PATH" };

    Process process = Runtime.getRuntime().exec( "su", envp );

    writer = new DataOutputStream( process.getOutputStream() );
    reader = new BufferedReader( new InputStreamReader( process.getInputStream() ) );

    writer.writeBytes( "export LD_LIBRARY_PATH=" + libPath + ":$LD_LIBRARY_PATH\n" );
    writer.flush();

但在这些设备上似乎没有任何工作......所以我开始认为这是一个与内核相关的问题,一些内核(比如我的)使用 LD_LIBRARY_PATH,其他内核不使用(简单地忽略它,或者它们是仅使用在应用程序启动时设置的 LD_LIBRARY_PATH,因此无法在运行时更改它)。

我也尝试使用 System.load 但它不起作用,可能是因为这些库不是 JNI ...在开始考虑使用静态链接的二进制文件之前我可以尝试一些东西吗?


这是我写的一个简单的包装:

#include <android/log.h>
#include <dlfcn.h>
#include <stdio.h>
#include <string.h>

typedef int (*main_t)(int argc, char** argv);

static int help(const char* argv0)
{
    printf("%s: simple wrapper to work around LD_LIBRARY_PATH\n\n", argv0);
    printf("Args: executable, list all the libraries you need to load in dependency order, executable again, optional parameters\n");
    printf("example: %s /data/local/ttte /data/data/app/com.testwrapper/lib/ttt.so /data/local/ttte 12345\n", argv0);
    printf("Note: the executable should be built with CFLAGS=\"-fPIC -pie\", LDFLAGS=\"-rdynamic\"\n");

    return -1;
}

int main(int argc, char** argv)
{
    int rc, nlibs;
    void *dl_handle;

    if (argc < 2)
    {
        return help(argv[0]);
    }

    __android_log_print(ANDROID_LOG_DEBUG, "wrapper", "running '%s'", argv[1]);

    for (nlibs = 2; ; nlibs++)
    {
        if (nlibs >= argc)
        {
            return help(argv[0]);
        }

        __android_log_print(ANDROID_LOG_DEBUG, "wrapper", "loading '%s'", argv[nlibs]);
        dl_handle = dlopen(argv[nlibs], 0); // do not keep the handle, except for the last
        __android_log_print(ANDROID_LOG_DEBUG, "wrapper", "loaded '%s' -> %p", argv[nlibs], dl_handle);
        if (strcmp(argv[1], argv[nlibs]) == 0)
        {
            break;
        }
    }

    main_t pmain = (main_t)dlsym(dl_handle, "main");
    __android_log_print(ANDROID_LOG_DEBUG, "wrapper", "found '%s' -> %p", "main", pmain);
    rc = pmain(argc - nlibs, argv + nlibs);

//   we are exiting the process anyway, don't need to clean the handles actually

//   __android_log_print(3, "wrapper", "closing '%s'", argv[1]);
//   dlclose(dl_handle);

    return 0;
}

为了保持其可读性,我放弃了大部分错误处理、不必要的清理和特殊情况的处理。

Android.mk对于这个可执行文件:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := wrapper
LOCAL_SRC_FILES := wrapper/main.c
LOCAL_LDLIBS    := -llog

include $(BUILD_EXECUTABLE)

请注意,您必须负责部署:将其打包wrapper进入 APK,解压到某个本地路径(切勿解压到 USB 存储或解压到/sdcard!),将其标记为可执行(chmod 777).

这些是您在构建通过以下方式运行的可执行文件时必须提供的附加参数:wrapper。如果你使用ndk-build构建它们,如下所示:

LOCAL_C_FLAGS   += -fPIC -pie
LOCAL_LDFLAGS   += -rdynamic 

请注意,您不需要chmod不再需要这些可执行文件了。另一个技巧:你可以构建中学可执行文件到共享库中,并且相同的包装器将继续工作!这省去了部署这些二进制文件的麻烦。 NDK 和 Android 构建将通过 APK 的 libs/armeabi 自动将它们安全地传送到应用程序的 lib 目录。

Update

似乎有一个更简单的解决方案,使用流程构建器 http://developer.android.com/reference/java/lang/ProcessBuilder.html修改环境:https://stackoverflow.com/a/8962189/192373 https://stackoverflow.com/a/8962189/192373.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 上有时会忽略 LD_LIBRARY_PATH 的相关文章

随机推荐

  • Python不打印输出

    我正在学习将 electro js 与 python 一起使用 并且我正在使用蟒蛇壳 https www npmjs com package python shell所以我有以下简单的Python脚本 import sys json sim
  • Python:可视化字典字典的最佳方式

    我想可视化以下字典中的字典 players info Afghanistan Asghar Stanikzai 809 0 Mohammad Nabi 851 0 Mohammad Shahzad 1713 0 Najibullah Zad
  • Laravel - 尝试在 ::first() 上获取非对象的属性

    好的 我明白了Trying to get property of non object当我尝试使用从数据库获取数据时 settings AdminSettings first 这是控制器代码
  • UITextField 获取当前编辑的单词

    我正在开发一个自动完成组件 我有一个问题想以某种简单的方式解决 我想支持对自动完成文本的编辑 例如 blablabl usertag blablabl 如果用户返回并编辑 usertag 字符串 我想在编辑时启动自动完成功能 问题是 如何从
  • Apache POI评估公式

    我的工作表单元格中有一些公式 我想在插入一些值后评估它们 前任 我的公式是 SUM B1 B2 插入值之前B1值为1 and B2值为3 公式结果为4 插入值后 现在 B1 有了值5 并且 B2 有值2但公式仍然产生4 我如何评估 触发这个
  • 使用 FQL 的随机好友

    我现在正在使用 fql 它将所有朋友列表放入数组中 然后我对该数组进行排序以获得随机朋友 但似乎需要很长时间 因为我必须收集所有朋友才能获得单个随机朋友 我如何在 fql 中找到随机好友 SELECT uid name pic sex FR
  • 搜索 WindowBuilder 文档/API

    我正在使用 WindowBuilder Pro 进行一个项目 在试图很好地掌握它的同时 我一直在寻找好的文档 但没有任何运气 我发现的最好的是Google WindowBuilder Pro 信息页面 http code google co
  • 带有 x86-64 组件的谐波系列

    尝试计算调和级数 现在我正在输入我想要添加的数字 当我输入像 1 2 这样的小数字时 程序只是停止 不会崩溃 它似乎正在进行计算 但它永远不会完成程序 这是我的代码 denominator xor r14 r14 zero out r14
  • MVC:我可以在控制器外的类内部使用 ModelState 吗?

    我可以在一节课上做这个吗 using System Web Mvc public static class aaa public static test if something ModelState AddModelError test
  • 安装 opencv-python-headless 需要很长时间

    当我安装时opencv python headless在 Google Colab 中 需要 15 分钟才能完成 My code pip install upgrade pip pip install opencv python headl
  • 在 Android studio 2.2.3 中找不到工具 > Firebase

    根据开发人员指南 https developer android com studio write firebase html https developer android com studio write firebase html 我
  • 验证库 (.lib) 中使用的 CRT

    如何检查 Windows 中的静态库 lib 链接到哪个运行时库 我正在使用 MDd 编译我的项目 并且我假设我链接到的库正在使用 MTd 多线程调试 Error 7 error LNK2005 public thiscall std Lo
  • 为什么我的手机无法访问电脑网络?

    我有一个问题 昨天我可以从手机访问我的计算机网络 但今天它不起作用 为什么会这样 我准备的东西 我已经使用 XAMPP 运行本地服务器 我已经开始Apache and MySQL 我通过 WIFI 连接到同一网络 我的手机是通过USB连接到
  • 在 IIS6 上使用 Decimal In Route 进行路由

    我的 MVC3 项目中有一条路线 当通过调试器和 IIS7 运行时 该路线在本地运行得非常好 但是 我们的服务器是 IIS6 当我将应用程序移出时 我收到 找不到页面 错误 我的猜测是这与路线中的小数有关 所以我尝试实现一个 RouteHa
  • 如何将参数传递给 webpack.config.js?

    我正在跟进these https www hipstercode com blog 27 指令基于this https github com vuejs templates webpack tree master template项目 官方
  • 在视图上创建全文索引时出现问题

    我有一个这样创建的视图 CREATE VIEW dbo vwData WITH SCHEMABINDING AS SELECT DataField1 DataField2 DataField3 FROM dbo tblData 当我尝试在其
  • 有时会出现模式关闭时的空白屏幕

    我有一个动态创建的表格 每行都有按钮 如果我单击按钮 模式将打开以输入模式后面带有黑屏的详细信息 单击接受按钮时 模式将关闭 黑屏必须消失 它有时会消失 但在其他情况下不会消失 这就是在模式中单击 接受 按钮后我的屏幕有时会出现的情况出现的
  • 无法调用基类的受保护函数?

    我无法在基类中调用受保护的函数 为什么 它看起来像这样 class B B2 public virtual f1 B 0 protected virtual f2 B codehere class D public B public vir
  • Matlab 中的相关可观测属性。有效吗?

    在 Matlab 类中 声明在语法上似乎是正确的property那是依赖者 计算未存储 和可观察的在同一时间 考虑代码 properties Access private instanceOfAnotherClass end propert
  • Android 上有时会忽略 LD_LIBRARY_PATH

    我有一个 Android 应用程序 它会生成许多与我随包分发的库动态链接的本机可执行文件 为了启动这些二进制文件 我使用 LD LIBRARY PATH 环境变量让它们知道从中加载库的位置 但在某些设备上这根本不起作用 LD LIBRARY