【问题标题】:Running a C binary from an android application : particulare case从 android 应用程序运行 C 二进制文件:特殊情况
【发布时间】:2016-05-13 11:08:54
【问题描述】:

我有一个要在 Android 上启动的 C 项目。

我使用 NDK 编译了项目,生成了二进制文件并将其嵌入到应用程序中以启动它。 该项目使用自动工具,我使用androgenizer 来生成和适配Android.mks。 它也使用openssl,所以我按照this为android编译它,二进制使用编译的libcrypto.so

应用程序只做:

  • 加载 libcrypto.so
  • 复制二进制文件
  • 执行二进制文件

这是一段代码

Process mybinProcess;
File target = new File(getFilesDir(), "mybin");
InputStream in = getResources().openRawResource(R.raw.mybin);

try {
    OutputStream out = new FileOutputStream(target);
    FileUtils.copy(in, out);
    FileUtils.chmod(target, 0755);

if(target.exists()){
    String[] command = {target.getAbsolutePath()};
    mybinProcess = Runtime.getRuntime().exec(command);
    BufferedReader output = FileUtils.getOuput(mybinProcess);
    BufferedReader error = FileUtils.getError(mybinProcess);

    // [...] print stdout et stderr

    mybinProcess.waitFor();
    int exitval=mybinProcess.exitValue(); //exit value is 1

标准输出给了我二进制文件的语法错误:

/data/data/com.myproject.mybin/files/mybin[1]: syntax error: ' 4   4' unexpected

当我尝试从 adb shell 启动二进制文件时,得到了那个错误

root@generic_x86:/data/user/0/com.myproject/files # ./mybin
/system/bin/sh: ./mybin: not executable: 32-bit ELF file

我在十六进制编辑器中打开mybin,语法错误出现在库/usr/lib/libc.so.1 的字符串之前。但是在模拟器上目录/usr 不存在。我认为它来自 ndk,ndk-build 的最后一个编译行包含来自<ndk>/platforms/android-19/arch-arm/usr/lib。此外,在<ndk>/platforms/android-19/arch-arm/usr/lib 中只有libc.so 而不是libc.so.1

知道我可以在哪里搜索以修复它,让它工作吗?


我的配置:

  • NDK:r11c
  • Android 平台:19
  • Android Studio : 2.1
  • SDK:r24.4.1
  • mybin (ndk) 在 Linux 上编译,apk (Android Studio) 在 Windows 上编译

【问题讨论】:

    标签: android c android-ndk


    【解决方案1】:

    构建一个在 Android 上运行的可执行文件是possible,但不是正确的方法 IMO,您应该为您的本机二进制库构建一个 JNI 接口并调用 C 库。

    这里有一个简单的例子:

    http://developer.android.com/ndk/samples/sample_hellojni.html

    如果您有很多 JNI 调用,我们使用 javacpp 生成 JNI 代码取得了很大成功。如果你只需要一两个电话,我可能会手写。

    【讨论】:

    • 如果我使用我的 C 代码作为库,我必须用 Java 重写整个项目。我想直接在 Android 上启动二进制文件,并按照 ndk build executable 指令生成了一个无法使用的可执行文件...
    • @raja.b If I uses my C code as a library, I have to rewrite the whole project in Java 我不确定我是否关注你。我建议保留 C 代码原样,但不要将 C 代码构建为可执行文件,而是使用一种或两种方法创建一个 C 库以从库中获取数据。然后在 java 端创建相同的 JNI 方法来与之交互。比处理命令界面和从输出中抓取文本要容易得多。如果您确实可以正常工作,但可能无法在所有设备上正常工作。
    • @GaryBack Much easier than dealing with the command interface and scraping text from the output. 。目前,不需要处理文本输出。这是进一步的步骤,在使二进制文件运行之后,使用 java 端进行接口将是最好的选择。我不明白的是,ndk 生成的二进制文件与目标平台不兼容(32 位错误,语法错误)。
    猜你喜欢
    • 2011-09-20
    • 2017-02-17
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 2014-01-16
    • 2012-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多