如何通过JNI/NDK获取Android应用程序中使用的c ++库的日志行(printf,cout等)的控制台输出

Isn*_*god 7 c++ console java-native-interface logging android-ndk

在我的Android应用程序中,我通过JNI使用本机c ++库.如果它以调试模式构建,则此库会生成日志行.我想将日志行重定向到logcat.

所以我在调试模式下创建了lib, NDK_DEBUG=1使用并 LOCAL_LDLIBS += -llog设置了.

我的设备没有root,但我设置:

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

就像它在http://developer.android.com/tools/debugging/debugging-log.html#viewingStd中描述的那样,这里的"std :: cout"可用于Android-ndk

使用__android_log_print(ANDROID_LOG_INFO, "foo", "Error: %s", foobar);正在工作,但它不是我的选项,因为c ++ lib也用于iOS应用程序,所以我不想更改本机代码.

我还尝试使用此设置获取在JNI包装器中创建的控制台输出(printf),但除了"__android_log_print"语句之外,输出也不会对logcat造成影响.

我是否错过了某些内容,或者重定向是否仅适用于root设备?

如何获取本机代码生成的控制台输出.

先感谢您

vgo*_*anz 13

我使用记录器标题来打印跨平台日志.

在c ++代码中只写LOGD("msg"); 或LOGE("msg"); 并打印检查平台的消息.

尝试创建跨平台日志标头,如:

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
Run Code Online (Sandbox Code Playgroud)


fad*_*den 5

如果您的设备没有 root,则adb shell stop/start命令将不起作用。这意味着 zygote 不会重新启动,因此它不会获取新log.redirect-stdio属性。无论如何,这个属性是一个黑客——它导致同一进程中的虚拟机创建一个线程,读取 stdout/stderr 并将它们转发到日志文件。

最好的办法是使用可变对数宏,该宏__android_log_print根据预处理器符号(例如__ANDROID__)在 iOS 想要的任何东西之间切换。然后它就会编译成正确的东西。