2012-02-08 16 views
13

Android'de çalıştırmak için mevcut bazı C kodlarını yerleştiriyorum. Bu C kodu, stdout/stderr'e çok sayıda çıktı yazar. Bu çıktıyı bir bellek arabelleğinde veya bir dosyada tutmam gerekiyor, böylece e-postayla gönderebilir veya başka bir şekilde paylaşabilirim.NDK ile stdout/stderr yakalama

İdeal olarak mevcut C kodunu değiştirmeden bunu nasıl başarabilirim?

Not: Bu soru, çıktıyı adb veya logcat'e yönlendirmekle ilgili NOT; Çıkışı cihaz üzerinde yerel olarak tamponlamam gerekiyor.

+0

C++ http://stackoverflow.com/questions/8870174/is-stdcout-usable-in-android-ndkl –

cevap

1

stdout'u yolu 1'dir ve stderr Bunu bilerek yolu 2., sen kurabilir: Ben sorunuza çözüm görünmüyor aşağıdaki soruların, farkındayım Çıkış hedefi olmak istediğiniz yeni yol (lar) sonra onları stdout ve/veya stderr'a zorlayın. Bunun nasıl yapılacağını gösteren bir örnek var: practical examples use dup or dup2.

+0

Ben Android hakkında özel bir şey burada var olduğunu işaret etmek istiyorum. Bu, çoğu unix benzeri sistemlerde işleri yapmanın normal yoludur. –

17

Stderr'i bir boruya yeniden yönlendirmek için böyle bir şey kullanın. LogCat için boru yazma diğer tarafında bir okuyucu var:

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); 
    } 
} 

Sen kendi iş parçacığı bu çalıştırmak isteyeceksiniz. Ben Java iplik dönmesi ve ardından Java konu çağrıyı böyle bu NDK kodu vardır:

new Thread() { 
    public void run() { 
     nativePipeSTDERRToLogcat(); 
    } 
}.start(); 
+2

Bu kod bir dosya tanımlayıcısını sızdırıyor - 'dup2()' çağrısından sonra kapatmanız (borular [1] ') yapmalısınız. Ayrıca, hataları kontrol etmelisiniz, ancak bu sistem çağrılarından herhangi biri başarısız olursa ne yapacağınızdan emin değilim. –

1

James Moore tarafından sunulan cevabı kullanılır, ama açık ve kapalı günlüğü çevirmek mümkün istedim. Bununla mKeepRunning öğesini false olarak ayarlayabilirim ve kapatılacak. Ayrıca, O_NONBLOCK bayrağını dosyaya eklemem gerekiyordu, böylece artık bir çağrı engelleme değildi.

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);