在JNI Android中如何向标准输出流(stdout)写入内容?不使用<android/log.h>头文件。

6

我已经修改了Android NDK的HelloJni示例,我想要向stdout写入一些东西。这里是JNI代码:

#include <stdlib.h>
#include <jni.h>
#include <stdio.h>

jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                              jobject thiz )
{
    printf("Hello from C !\n");
    return (*env)->NewStringUTF(env, "Hello from JNI !");
}

这是我的日志:

09-28 13:07:02.906: I/ActivityManager(1650): START {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.example.hellojni/.HelloJni u=0} from pid 1790
09-28 13:07:03.007: D/dalvikvm(1650): GC_FOR_ALLOC freed 687K, 10% free 9300K/10247K, paused 62ms, total 62ms
09-28 13:07:03.070: D/dalvikvm(3562): Not late-enabling CheckJNI (already on)
09-28 13:07:03.085: I/ActivityManager(1650): Start proc com.example.hellojni for activity com.example.hellojni/.HelloJni: pid=3562 uid=10052 gids={1015, 1028}
09-28 13:07:03.101: I/dalvikvm(3562): Turning on JNI app bug workarounds for target SDK version 3...
09-28 13:07:03.132: D/dalvikvm(3562): Debugger has detached; object registry had 1 entries
09-28 13:07:03.171: D/dalvikvm(3562): Trying to load lib /data/data/com.example.hellojni/lib/libhello-jni.so 0x414af318
09-28 13:07:03.179: D/dalvikvm(3562): Added shared lib /data/data/com.example.hellojni/lib/libhello-jni.so 0x414af318
09-28 13:07:03.179: D/dalvikvm(3562): No JNI_OnLoad found in /data/data/com.example.hellojni/lib/libhello-jni.so 0x414af318, skipping init
09-28 13:07:03.265: V/TabletStatusBar(1715): setLightsOn(true)
09-28 13:07:03.328: I/ActivityManager(1650): Displayed com.example.hellojni/.HelloJni: +279ms
09-28 13:07:07.078: E/ThrottleService(1650): problem during onPollAlarm: java.lang.IllegalStateException: problem parsing stats: java.io.FileNotFoundException: /proc/net/xt_qtaguid/iface_stat_all: open failed: ENOENT (No such file or directory)

我已将log.redirect-stdio设置为true,这样我就能在LogCat中看到“Hello”行。
有人知道如何使它起作用吗?谢谢。
更明确地说,我想要看到我的输出在stdout中。没有什么问题,我只是想知道是否可以输出到stdout。感谢提供解决方案的人使用__android_log_print。

1
更明确地说,我想要做的是在stdout中看到我的输出,这只是一个小测试,以查看是否可以在JNI中完成。使用<android/log.h>没有问题,我只想知道是否可以输出到stdout。 - user1706070
重定向功能适用于模拟器或已获取 root 权限的设备。 - Alex Cohn
可能是重复的问题:在Android-ndk中是否可以使用"std :: cout" - Ciro Santilli OurBigBook.com
3个回答

16

Android Studio

如果您使用 Android Studio 和 Gradle,那么它会忽略 Android.mk 文件。请将以下内容添加到您的 build.gradle 文件中:

android {
    defaultConfig {
        ndk {
            moduleName "your_module_name"
            ldLibs "log"
        }
    }
}

Eclipse

你需要在Android.mk文件中添加LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog

你只需要定义自己的辅助宏,就像这样...

#include <android/log.h>

#define LOGV(TAG,...) __android_log_print(ANDROID_LOG_VERBOSE, TAG,__VA_ARGS__)
#define LOGD(TAG,...) __android_log_print(ANDROID_LOG_DEBUG  , TAG,__VA_ARGS__)
#define LOGI(TAG,...) __android_log_print(ANDROID_LOG_INFO   , TAG,__VA_ARGS__)
#define LOGW(TAG,...) __android_log_print(ANDROID_LOG_WARN   , TAG,__VA_ARGS__)
#define LOGE(TAG,...) __android_log_print(ANDROID_LOG_ERROR  , TAG,__VA_ARGS__)

效果非常好。


当使用Android Studio与Gradle时,Android.mk文件会被忽略。请参阅https://dev59.com/iofca4cB1Zd3GeqPdAAi#28004606。 - Alan Kazbekov

15

使用Android日志记录函数:

#include <android/log.h>
.... 
__android_log_print(ANDROID_LOG_VERBOSE, "MyApp", "The value of n is %d", n);

提醒:在问题被编辑之前阅读此内容的人请注意:最初问题并未规定OP不想使用`<android / log.h>`中的函数。


4

如果您想通过本机代码打印到Logcat,您需要使用Android的本机Logger。

大致如下:

#include <jni.h>
#include <android/log.h>

#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,DEBUG_TAG,__VA_ARGS__)
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,DEBUG_TAG,__VA_ARGS__)

然后您在函数内部使用它:

LOGD("hello");

为了使其正常工作,您需要向编译中添加本机LOG(Android.mk)。
LOCAL_LDLIBS :=  -llog 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接