弹幕网站制作/无锡哪里有做网站的
我正在移植一些现有的C代码以在Android上运行。 此C代码将大量输出写入stdout / stderr。 我需要在内存缓冲区或文件中捕获此输出,以便随后可以通过电子邮件发送或共享它。
我如何才能做到这一点,理想情况下无需修改现有的C代码?
注意:这个问题不是关于将输出重定向到adb或logcat的。 我需要在设备上本地缓冲输出。 我知道以下问题似乎无法解决我的查询:
为什么在Android上重定向stdout / stderr不起作用?
Android NDK本机LIB,如何处理现有的stdio?
C ++ stackoverflow.com/questions/8870174/
使用类似这样的东西将stderr重定向到管道。 在管道的另一侧有一个读者来写logcat:
extern"C" void Java_com_test_yourApp_yourJavaClass_nativePipeSTDERRToLogcat(JNIEnv* env, jclass cls, jobject obj)
{
int pipes[2];
pipe(pipes);
dup2(pipes[1], STDERR_FILENO);
FILE *inputFile = fdopen(pipes[0],"r");
char readBuffer[256];
while (1) {
fgets(readBuffer, sizeof(readBuffer), inputFile);
__android_log_write(2,"stderr", readBuffer);
}
}
您将要在其自己的线程中运行它。 我启动Java中的线程,然后让Java线程像下面这样调用此NDK代码:
new Thread() {
public void run() {
nativePipeSTDERRToLogcat();
}
}.start();
这段代码泄漏了文件描述符-调用dup2()后应该close(pipes[1])。 另外,您应该检查是否有错误,尽管我不太确定如果这些系统调用中的任何一个失败,您会怎么做。
我使用了James Moore提交的答案,但是我希望能够打开和关闭日志记录。 这样,我可以将mKeepRunning设置为false,它将关闭。 我还需要将O_NONBLOCK标志添加到文件中,因此它不再是阻塞调用。
int lWriteFD = dup(STDERR_FILENO);
if ( lWriteFD < 0 )
{
// WE failed to get our file descriptor
LOGE("Unable to get STDERR file descriptor.");
return;
}
int pipes[2];
pipe(pipes);
dup2(pipes[1], STDERR_FILENO);
FILE *inputFile = fdopen(pipes[0],"r");
close(pipes[1]);
int fd = fileno(inputFile);
int flags = fcntl(fd, F_GETFL, 0);
flags |= O_NONBLOCK;
fcntl(fd, F_SETFL, flags);
if ( nullptr == inputFile )
{
LOGE("Unable to get read pipe for STDERR");
return;
}
char readBuffer[256];
while (true == mKeepRunning)
{
fgets(readBuffer, sizeof(readBuffer), inputFile);
if ( strlen(readBuffer) == 0 )
{
sleep(1);
continue;
}
__android_log_write(ANDROID_LOG_ERROR,"stderr", readBuffer);
}
close(pipes[0]);
fclose(inputFile);
stdout是路径1,stderr是路径2。知道这一点后,您可以建立要用作输出目标的新路径,然后将其强制为stdout和/或stderr。 在实际示例中,使用dup或dup2演示了如何执行此操作。
我想指出,这里的Android没有什么特别之处。 这是在大多数类Unix系统上执行操作的正常方法。