【问题标题】:How to compile C into an executable binary file and run it in Android from Android Shell?如何将 C 编译成可执行的二进制文件并从 Android Shell 在 Android 中运行?
【发布时间】:2012-04-09 17:33:04
【问题描述】:

我有一台安装了 Android Gingerbread 2.3.4 的设备 这里我想在android设备上运行C可执行文件

我能够在此设备上运行 android NDK 应用程序,并且运行良好。 但我只想在设备上运行一个hello.c 可执行文件。

/* #includes #defines ... */

int main(){
    // Do something when this is executed
    return 0;
}

有没有什么方法可以用Android NDK 工具链编译这个文件,这样我就可以运行这个文件的可执行文件了?

我发现了一件事 here 但这对我不起作用。我在 Linux 上使用Android NDK, Revision 7b。 没有这样的目录结构。

【问题讨论】:

标签: android c android-ndk


【解决方案1】:

首先,让我说我的答案取决于您在 Linux 上使用 NDK r7b(它也适用于 r7c)(为其他系统适当更改路径)。

编辑:上次在 Linux 上使用 NDK r8e 和 Nexus 4 在 Windows 7 上使用 adb 和 SDK Platform-Tools Rev 18 进行测试(最新于 2013 年 7 月 25 日)没有 root 访问权限。

又一次编辑:请阅读 this question 以更改我对需要在 Android 5.0(Lollypop) 及更高版本上运行的本机二进制文件的说明。

  1. 转到$NDK_ROOT(解压时NDK zip的最顶层文件夹)。
  2. 将$NDK_ROOT/samples/hello-jni目录复制为$NDK_ROOT/sources/hello-world。
  3. 转到$NDK_ROOT/sources/hello-world。
  4. 编辑AndroidManifest.xml 为应用程序提供适当的名称(这是可选的)。
  5. 转到$NDK_ROOT/sources/hello-world/jni。这是源代码所在。
  6. 编辑hello-jni.c,删除所有代码,然后输入您的hello world 代码。我的是:
    #include
    int main(int argc, char* argv[])
    {
        printf("你好,世界!");
        返回0;
    }
  7. 编辑Android.mk 并将include $(BUILD_SHARED_LIBRARY) 行更改为include $(BUILD_EXECUTABLE)。您还可以将LOCAL_MODULE 行更改为您想要的可执行文件名称(默认为hello-jni)
  8. 返回$NDK_ROOT/sources/hello-world
  9. 运行../../ndk-build 以创建可执行文件。
  10. 在 Android 设备上将其从 $NDK_ROOT/sources/hello-jni/libs/armeabi/hello-jni 复制到 /data/local/tmp 并将其权限更改为 755 (rwxr-xr-x)。如果您更改了$NDK_ROOT/sources/hello-world/jni/Android.mk 中的LOCAL_MODULE 行,则可执行文件名称将是LOCAL_MODULE 的新值,而不是hello-jni。 (所有这些都是通过 Android SDK 中的adb 完成的。)
  11. 以/data/local/tmp/hello-jni 的完整路径执行二进制文件,或者任何你命名的文件。

您已经完成了(可以开始阅读 $NDK_ROOT/docs 中的文档以更好地了解要做什么)。

【讨论】:

  • samples 目录下有test-libstdc++ 项目,看起来正是您要解释的内容。
【解决方案2】:

放置可执行文件的最佳/最简单的位置是 /data/local。您还需要将chmod 二进制文件作为可执行文件。通常,您还需要分两步执行此操作,以将二进制文件从 /sdcard/ 获取到 /data/local:

$ adb push mybin /sdcard/
$ adb shell
$ cp /sdcard/mybin /data/local/mybin
$ cd /data/local
$ chmod 751 mybin

注意事项:

  • 并非所有系统都有cp。如果是这种情况,您可以使用cat:

    $ cat /sdcard/mybin > /data/local/mybin

  • 某些系统不允许“shell”用户写入/data/local。试试/data/local/tmp

【讨论】:

  • 您是说二进制文件本身在运行时崩溃?如果是这种情况,我建议您针对那里的具体问题提出一个新问题。
  • 我在说什么?我无法执行这个 C 二进制文件。我怎样才能做到这一点?
  • 是的,您需要 root 才能在应用程序的沙箱范围之外进行游戏。
  • 不正确,您不需要需要root,您只需将二进制文件放在应用程序可写的位置,例如其私有目录。
  • 此外,无需将文件推送到 scard,然后将其移动到 /data/local(或者更可能是 /data/local/tmp)——如果你可以将它移动到那里,你可以用 adb push 把它放在那里。
【解决方案3】:

“/sdcard”位置不可执行,这意味着那里的任何文件都不可执行。

“adb push”可执行文件的唯一方法是将它们放在“/data/local”中,这对 adb 应该是可写的,并允许任何人执行。

【讨论】:

  • 在 Lollipop 中(在我的 Xperia Z3 上)我需要将它复制到 /data/local/tmp 并且有效。
【解决方案4】:

我最近在新的 nexus-5 上遇到了同样的问题。我想补充一点,我使用 adb shell 获得的 /data/local 用户不可写(“shell”,uid 2000)。但是将可执行文件放在子目录 /data/local/tmp/ 中效果很好。

【讨论】:

    【解决方案5】:

    简而言之,

    首先,要从主机交叉编译 C 代码,请使用带有 sysroot 选项和位置无关选项 -fPIE -pie 的 NDK 工具链。

    $NDKROOT/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-gcc \
    --sysroot=$NDKROOT/platforms/android-22/arch-arm64 -fPIE -pie main.c -o main
    

    架构部分arrch64或arch-arm64,工具链版本部分4.9,平台版本部分android-22, 主机 darwin-x86_64 的二进制格式可能因您的环境而异。

    其次,将您的二进制文件推送到/data/local/tmp 下并从adb shell 执行它。

    【讨论】:

      猜你喜欢
      • 2016-04-08
      • 1970-01-01
      • 2011-05-06
      • 2013-12-02
      • 1970-01-01
      • 2016-04-02
      • 2012-09-02
      相关资源
      最近更新 更多