Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get console output of log lines (printf, cout ,etc...) of c++ library used in Android app via JNI/NDK

in my Android app I use a native c++ library via JNI. This library produces log lines, if its build in debug mode. I want to have the log lines redirected to logcat.

So I created the lib in debug mode, NDK_DEBUG=1 is used and LOCAL_LDLIBS += -llog is set.

My devices is not rooted but I set:

$ adb shell stop $ adb shell setprop log.redirect-stdio true $ adb shell start

Like it was described at http://developer.android.com/tools/debugging/debugging-log.html#viewingStd and here Is "std::cout" usable in Android-ndk

Using __android_log_print(ANDROID_LOG_INFO, "foo", "Error: %s", foobar); is working but it is not an option for me because the c++ lib is also used for an iOS app so I dont want to change the native code.

I also tried to get the console output (printf) created in the JNI wrapper with this settings but except the "__android_log_print" statements the output is not visble a logcat too.

Did I missed something or is the redirection only possible for rooted devices?

How can I get the console output produced by native code.

Thank You in Advance

like image 424
Isnogod Avatar asked Jun 20 '14 10:06

Isnogod


2 Answers

I use a logger header to print crossplatform logs.

In c++ code just write LOGD("msg"); or LOGE("msg"); and print messages checking the platform.

Try creating a crossplatform log header like:

Logs.h

#       ifdef ANDROID
            // LOGS ANDROID
#           include <android/log.h>
#           define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG,__VA_ARGS__)
#           define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG  , LOG_TAG,__VA_ARGS__)
#           define LOGI(...) __android_log_print(ANDROID_LOG_INFO   , LOG_TAG,__VA_ARGS__)
#           define LOGW(...) __android_log_print(ANDROID_LOG_WARN   , LOG_TAG,__VA_ARGS__)
#           define LOGE(...) __android_log_print(ANDROID_LOG_ERROR  , LOG_TAG,__VA_ARGS__)
#           define LOGSIMPLE(...)
#       else
            // LOGS NO ANDROID
#           include <stdio.h>
#           define LOGV(...) printf("  ");printf(__VA_ARGS__); printf("\t -  <%s> \n", LOG_TAG);
#           define LOGD(...) printf("  ");printf(__VA_ARGS__); printf("\t -  <%s> \n", LOG_TAG);
#           define LOGI(...) printf("  ");printf(__VA_ARGS__); printf("\t -  <%s> \n", LOG_TAG);
#           define LOGW(...) printf("  * Warning: "); printf(__VA_ARGS__); printf("\t -  <%s> \n", LOG_TAG);
#           define LOGE(...) printf("  *** Error:  ");printf(__VA_ARGS__); printf("\t -  <%s> \n", LOG_TAG);
#           define LOGSIMPLE(...) printf(" ");printf(__VA_ARGS__);
#       endif // ANDROID
like image 55
vgonisanz Avatar answered Nov 03 '22 12:11

vgonisanz


If your device is not rooted, the adb shell stop / start commands will have no effect. That means zygote won't restart, so it won't pick up the new log.redirect-stdio property. This property is something of a hack anyway -- it causes a VM in the same process to create a thread that reads stdout/stderr and forwards them to the log file.

Your best bet is to use a variadic log macro that switches between __android_log_print and whatever iOS wants based on a preprocessor symbol (e.g. __ANDROID__). Then it'll just compile to the right thing.

like image 27
fadden Avatar answered Nov 03 '22 11:11

fadden