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

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

本文关键字:printf 日志 cout 输出 控制台 c++ 获得 NDK JNI Android 应用      更新时间:2023-10-16

在我的Android应用中,我通过JNI使用了一个本地c++库。如果在调试模式下构建,该库将生成日志行。我想把日志行重定向到logcat。

所以我在调试模式下创建了这个库,使用NDK_DEBUG=1和设置LOCAL_LDLIBS += -llog

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

$ 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++库也用于iOS应用程序,所以我不想改变本机代码。

我也试图用这个设置在JNI包装器中创建控制台输出(printf),但除了"__android_log_print"语句外,输出也不可见。

我错过了什么还是重定向只适用于根设备?

如何获得本机代码生成的控制台输出。

提前感谢

我使用一个日志头来打印跨平台日志。

在c++代码中只写LOGD("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

如果您的设备没有根,adb shell stop/start命令将不起作用。这意味着受精卵不会重新启动,所以它不会选择新的log.redirect-stdio属性。无论如何,这个属性是一种hack——它导致同一进程中的VM创建一个线程来读取stdout/stderr并将它们转发到日志文件。

你最好的选择是使用可变日志宏,在__android_log_print和任何iOS想要的基于预处理器符号(例如__ANDROID__)之间切换。然后它就会编译成正确的东西