2012-02-08 13 views
13

के साथ stdout/stderr को कैप्चर करना मैं एंड्रॉइड पर चलाने के लिए कुछ मौजूदा सी कोड पोर्ट कर रहा हूं। यह सी कोड stdout/stderr के लिए बहुत सारे आउटपुट लिखता है। मुझे इस आउटपुट को मेमोरी बफर या फ़ाइल में कैप्चर करने की ज़रूरत है, इसलिए मैं इसे ईमेल द्वारा भेज सकता हूं या अन्यथा इसे साझा कर सकता हूं।एनडीके

मैं मौजूदा सी कोड को संशोधित किए बिना आदर्श कैसे प्राप्त कर सकता हूं?

नोट: यह प्रश्न आउटपुट को एडब या लॉगकैट पर रीडायरेक्ट करने के बारे में नहीं है; मुझे डिवाइस पर स्थानीय रूप से आउटपुट बफर करने की आवश्यकता है।

+0

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

उत्तर

1

stdout पथ 1 है और stderr यह जानने के बाद पथ 2. है, तो आप स्थापित कर सकते हैं: मैं निम्नलिखित प्रश्नों, जो अपनी क्वेरी को संबोधित करने नहीं दिखाई देते हैं के बारे में पता कर रहा हूँ नया पथ जो आप आउटपुट गंतव्य बनना चाहते हैं, फिर उन्हें stdout और/या stderr में समन्वयित करें। एक उदाहरण है कि यह practical examples use dup or dup2 पर कैसे करें।

+0

मैं यहाँ Android के बारे में कुछ खास नहीं है कि बाहर बिंदु करना चाहते हैं। अधिकांश यूनिक्स जैसी प्रणालियों पर चीजों को करने का यह सामान्य तरीका है। –

17

स्टीडर को पाइप पर रीडायरेक्ट करने के लिए ऐसा कुछ उपयोग करें। पाइप के दूसरी तरफ एक पाठक लॉगकैट पर लिखें:

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

आप इसे अपने स्वयं के धागे में चलाने के लिए चाहते हैं। मैं जावा में धागा ऊपर स्पिन और फिर जावा धागा कॉल इस तरह इस NDK कोड है:

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

यह कोड एक फ़ाइल डिस्क्रिप्टर को लीक करता है - आपको 'dup2() 'पर कॉल के बाद' बंद करें (पाइप [1]') होना चाहिए। साथ ही, आपको त्रुटियों की जांच करनी चाहिए, हालांकि मुझे पूरा यकीन नहीं है कि अगर आप इनमें से कोई भी सिस्टम कॉल विफल हो जाए तो आप क्या करेंगे। –

1

मैं जवाब जेम्स मूर द्वारा प्रस्तुत करते थे, लेकिन मैं और बंद पर लॉगिंग चालू करने के लिए सक्षम होने के लिए करना चाहता था। इसके साथ मैं mKeepRunning को झूठी पर सेट कर सकता हूं और यह बंद हो जाएगा। मुझे फ़ाइल में 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);