簡體   English   中英

使用NDK捕獲stdout / stderr

[英]Capturing stdout/stderr with NDK

我正在移植一些現有的C代碼以在Android上運行。 此C代碼將大量輸出寫入stdout / stderr。 我需要在內存緩沖區或文件中捕獲此輸出,以便我可以通過電子郵件或其他方式共享它。

如何在不修改現有C代碼的情況下實現這一目標?

注意:這個問題不是關於將輸出重定向到adb或logcat; 我需要在設備上本地緩沖輸出。 我知道以下問題,但似乎沒有解決我的問題:

使用類似的東西將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();

我使用了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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM