交叉编译Android的C代码

时间:2017-11-15 18:26:39

标签: android c android-ndk libc bionic

我使用 Ubuntu 16.04 LTS 下的 arm-linux-gnueabi 工具交叉编译 Android ARM 的C应用程序。我用静态链接标志编译它。这个C应用程序很大,并且它有复杂的makefile。它编译成功没有任何错误。但它在Android手机和Ubuntu PC上表现出不同。更确切地说,我有两个问题:

  1. popen()system()功能在Android上无效。它们被执行但什么都不做,不会给出任何错误。我用脏黑客解决了这个问题。
  2. fgets()功能在Android上很奇怪。
  3. 1。关于第一个问题。

    我进行了小规模研究,发现Android不使用普通的 libc 库( glibc 或其他正确实现POSIX标准的库)。它使用 Bionic 库代替它(抱歉,Android是我的新操作系统)。我查看了popen()system()函数代码,发现这些函数使用了_PATH_BSHELL个宏。 _PATH_BSHELL是实际系统shell的路径。此路径在Android上为“ / system / bin / sh ”,在Ubuntu上为“ / bin / sh ”。

    当我理解它时,我试图挂钩popen()system()函数。我从 Bionic 源复制了这些函数的代码,而不是我定义的宏#define _MY_PATH_BSHELL "/system/bin/sh",并通过execve(_MY_PATH_BSHELL, argp, environ);调用替换了execve(_MY_PATH_BSHELL, argp, environ);之类的调用。所以它开始正常工作。

    2。关于第二个问题。

    在Ubuntu上,这段代码可以正常运行:

    is_received = false;
    while(!is_received) {
        FILE *cmd = popen(command, "r");
        is_received = fgets(buf, sizeof(buf), cmd) == NULL ? false : true; 
    }
    

    但在Android fgets()上始终返回NULL,此循环无限长。我尝试使用read()函数而不是fgets()并且它有效。 在Android上,read()的代码正常运行:

    is_received = false;
    while(!is_received) {
        FILE *cmd = hooked_popen(command, "r");
        int fd = fileno(cmd);
        is_received = read(fd, buf, sizeof(buf)) == 0 ? false : true;
    }
    

    我的问题。

    1. 如何正确,正确地解决popen()system()的问题?我想我必须静态链接 Bionic 库。这样对吗?如何在没有Android Studio的情况下在控制台中执行此操作?我读到有必要使用 NDK ,但我不清楚如何。
    2. 为什么fgets()行为在Android和Ubuntu上不相似?

0 个答案:

没有答案