android - studio - ndk r13
Redirigir stdout a logcat en Android NDK (6)
No puedo obtener mi Nexus S (con Android 4.0) para redirigir el mensaje nativo de stdout a logcat. He leído que necesito hacer esto:
$ adb shell stop
$ adb shell setprop log.redirect-stdio true
$ adb shell start
Sin embargo, esto no parece funcionar. (Sin embargo, rompe JUnit, como se menciona here , por lo que no deja de tener efecto).
Como referencia, aquí está mi código:
package com.mayastudios;
import android.util.Log;
public class JniTester {
public static void test() {
Log.e("---------", "Start of test");
System.err.println("This message comes from Java.");
void printCMessage();
Log.e("---------", "End of test");
}
private static native int printCMessage();
static {
System.loadLibrary("jni_test");
}
}
Y el archivo JNI .c:
JNIEXPORT void JNICALL
Java_com_mayastudios_JniTester_printCMessage(JNIEnv *env, jclass cls) {
setvbuf(stdout, NULL, _IONBF, 0);
printf("This message comes from C (JNI)./n");
fflush(stdout);
//setvbuf(stderr, NULL, _IONBF, 0);
//fprintf(stderr, "This message comes from C (JNI)./n");
//fflush(stderr);
}
Y el Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := jni_test
LOCAL_SRC_FILES := test_jni.c
include $(BUILD_SHARED_LIBRARY)
Estoy compilando esto simplemente llamando a ndk-build
. El método nativo se llama correctamente pero no obtengo ningún resultado de registro (incluso en verbose). Sin embargo, obtengo el resultado de registro de Java ("Este mensaje proviene de Java").
¿Algún indicio de lo que podría estar haciendo mal?
PD: He creado un pequeño repositorio de Mercurial que demuestra el problema: https://bitbucket.org/skrysmanski/android-ndk-log-output/
Aquí el código que uso para dar salida a stdout y stderr al registro de Android
#include <android/log.h>
#include <pthread.h>
#include <unistd.h>
static int pfd[2];
static pthread_t loggingThread;
static const char *LOG_TAG = "YOU APP LOG TAG";
static void *loggingFunction(void*) {
ssize_t readSize;
char buf[128];
while((readSize = read(pfd[0], buf, sizeof buf - 1)) > 0) {
if(buf[readSize - 1] == ''/n'') {
--readSize;
}
buf[readSize] = 0; // add null-terminator
__android_log_write(ANDROID_LOG_DEBUG, LOG_TAG, buf); // Set any log level you want
}
return 0;
}
static int runLoggingThread() { // run this function to redirect your output to android log
setvbuf(stdout, 0, _IOLBF, 0); // make stdout line-buffered
setvbuf(stderr, 0, _IONBF, 0); // make stderr unbuffered
/* create the pipe and redirect stdout and stderr */
pipe(pfd);
dup2(pfd[1], 1);
dup2(pfd[1], 2);
/* spawn the logging thread */
if(pthread_create(&loggingThread, 0, loggingFunction, 0) == -1) {
return -1;
}
pthread_detach(loggingThread);
return 0;
}
Esto no fue obvio para mí de las respuestas anteriores. Incluso en dispositivos rooteados necesitas ejecutar:
adb root
adb shell stop
adb shell setprop log.redirect-stdio true
adb shell start
Intenta poner fflush(stdout);
después de su printf. O alternativamente, use fprintf(stderr, "This message comes from C (JNI)./n")
;
stdout por defecto es buffering. stderr - no es. Y está utilizando System.err, no System.out desde Java.
También puede deshabilitar el almacenamiento en búfer stdout con esto: setvbuf(stdout, NULL, _IONBF, 0);
Solo asegúrate de llamar antes de la primera llamada printf.
También debería poder ajustar su código de registro para detectar si es Android y, de ser así, usar el registro de Android. Esto puede o no ser práctico para todos.
Incluye el archivo de encabezado de registro:
#include <android/log.h>
Use la funcionalidad integrada de registro:
__android_log_print(ANDROID_LOG_INFO, "foo", "Error: %s", foobar);
stdout / stderr se redirigen a /dev/null
en las aplicaciones de Android. La solución setprop es un truco para dispositivos rooteados que copia stdout / stderr al registro. Ver Android Native Code Debugging .
setprop log.redirect-stdio true
redirige solo la salida generada por el código java, pero no el código nativo . Este hecho se describe en developer.android.com de la siguiente manera:
Por defecto, el sistema Android envía salida stdout y stderr (System.out y System.err) a / dev / null. En los procesos que ejecutan la VM Dalvik, puede hacer que el sistema escriba una copia de la salida en el archivo de registro.
Para obtener el resultado del código nativo, realmente me gustó esta solución