【问题标题】:popen on android NDK在 android NDK 上弹出
【发布时间】:2012-01-18 13:29:06
【问题描述】:

android NDK 不支持 popen 吗?

我阅读了this page 并想知道这是不是真的

POSIX popen() 也可以,但目前还不行 受仿生支持,因此您不能在 Android JNI 中使用它。相反,你 可能可以使用 system() 并将输出通过管道传输到文件,然后 之后阅读该文件。看起来Java方法将是 如果您将使用 Java 进行渲染,则更清晰。

但我也读到有人建议使用 popen。我自己也试过,但有时我的应用程序崩溃了,我不知道为什么。

popen 在 android ndk 中使用安全吗?

【问题讨论】:

    标签: android android-ndk popen


    【解决方案1】:

    我认为这取决于您使用的 NDK 版本

    同时在姜饼源代码树中寻找仿生,我确实找到了 popen 的实现。 实现可能不是 100% 正确的 libc,但它至少在某种程度上是功能性的。

    使用 NDK v6,以下示例编译没有任何问题,并且可以在我的 android 设备上运行。

    #include <stdio.h>
    #include <stdlib.h>
    int main()
    {
     FILE *fpipe;
     char *command="/system/bin/ps";
     char line[256];
     if ( !(fpipe = (FILE*)popen(command,"r")) ) exit(1)
     while ( fgets( line, sizeof line, fpipe))
     {
       puts(line);
     }
     pclose(fpipe);
    }
    

    更新: 似乎在使用 vfork() 而不是 fork() 的前 ICS 版本上 popen,并且已知那些 vfork() 会导致堆栈损坏。

    因此,从 ICS 开始,popen 应该可以保存使用,但在早期的 android 版本上它是可用的,但非常有问题。

    【讨论】:

      【解决方案2】:

      确实,popen() 无法在 Android 上运行。正如GLIBC description 所说,任何UNIX 操作系统都需要一个C 库来进行所有系统调用。其中包括线程内存分配、文件处理等。由于 Android 是基于 Linux 的,它需要实现这样的库,但由于它是一个小型移动操作系统,谷歌决定编写一个名为 bionic 的 libc 的“精简版”。这个库不包含popen(),因此你不能使用它。 NDK 文档中有对仿生库的描述,它位于您的 NDK 目录中(由于某种原因它不在线)。希望这会有所帮助。

      【讨论】:

      • 谢谢。我只是想知道它如何在我的示例应用程序上运行?我相信如果它不包括在内,那么它根本不应该工作。
      • 是的,这是正确的。虽然 popen() 函数在 Android 上可用,但它实际上破坏了堆栈,因为使用了 vfork() 方法。
      • 对我来说,popen/pclose 在我调用它们少于 4-5 次时起作用。我在这上面浪费了很多时间。
      • @ales-teska 你知道现在还是这样吗?因为我在 android 上遇到了 popen() 的非常奇怪的错误,现在是 2019 年......
      • @Slava - 不,我们不在 Android 上使用它
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多