1. 程式人生 > >JNI除錯C/C++的log列印

JNI除錯C/C++的log列印

1. 匯入log標頭檔案

你一定非常熟悉在Java程式碼中使用Log.x(TAG,“message”)系列方法,在c/c++程式碼中也一樣,不過首先你要include相關標頭檔案。遺憾的是你使用不同的編譯環境( 請參考上文中兩種編譯環境的介紹) ,對應的標頭檔案略有不同。。

(1)如果是在完整原始碼編譯環境下,只要include <utils/Log.h>標頭檔案,就可以使用對應的LOGI、LOGD等方法了,同時請定義LOG_TAG,LOG_NDEBUG等巨集值,示例程式碼如下:

#define LOG_TAG "HelloJni"  
#define LOG_NDEBUG 0  
#define LOG_NIDEBUG 0  
#define LOG_NDDEBUG 0  //本人親自測試過,加入這個後,還是報錯error: undefined reference to 'LOGI',把這個刪了在Android.mk檔案中加入libutils
  
#include <string.h>  
#include <jni.h>  
#include <utils/Log.h>  
jstring Java_com_inc_android_ime_HelloJni_stringFromJNI(JNIEnv* env,jobject thiz){  
    LOGI("Call stringFromJNI!\n");  
    return (*env)->NewStringUTF(env, "Hello from JNI (中文)!");  
}

與日誌相關的.h標頭檔案,在以下原始碼路徑:

  • myeclair\frameworks\base\include\utils\Log.h
  • myeclair\system\core\include\cutils\log.h

(2)如果你是在NDK環境下編譯,則需要#include <android/log.h>

#define LOG_TAG "HelloJni"  
  
#include <string.h>  
#include <jni.h>  
#include <utils/Log.h>  
jstring Java_com_inc_android_ime_HelloJni_stringFromJNI(JNIEnv* env,jobject thiz){  
    __android_log_print(ANDROID_LOG_INFO,LOG_TAG,"Call stringFromJNI!\n");  
    return (*env)->NewStringUTF(env, "Hello from JNI (中文)!");  
}


2.在Android.mk 中

ifeq ($(HOST_OS),windows)  
#NDK環境下  
    LOCAL_LDLIBS := -llog  
else  
#完整原始碼環境下  
    LOCAL_SHARED_LIBRARIES += \
         libcutils libutils   
endif



3. 定義LOG 函式

很可惜,其中用於日誌輸出的方法是:__android_log_print(....) 並不是我們熟悉的LOG.x(...)系列方法。不過好的一點是android/log.h檔案在完整原始碼環境下也是可用的,因此,可以用一下的標頭檔案來統兩種環境下的差異:


先定義一個全域性變數,再定義一些輸出的LOG函式:

#define TAG "myDemo-jni" // 這個是自定義的LOG的標識
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__) // 定義LOGD型別
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__) // 定義LOGI型別
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG ,__VA_ARGS__) // 定義LOGW型別
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG ,__VA_ARGS__) // 定義LOGE型別
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,TAG ,__VA_ARGS__) // 定義LOGF型別

上述程式碼中定義的函式

分別對應於Android 的Java程式碼中的

 Log.d(), Log.i(), Log.w(),Log.e(), Log.f()等方法.


4.舉例

void Java_com_himedia_jni_NativeMethod_setLogo
  (JNIEnv * env, jobject thiz, jstring prompt)
{
	/*(*env)->NewStringUTF(env, "哈哈完成自動化編譯 !")*/

	 const jbyte *str;

	 str = (*env)->GetStringUTFChars(env, prompt, NULL);
	 if (str == NULL) {
		 return NULL; /* OutOfMemoryError already thrown */
	 }

	 LOGD("########## str = %s", str);

	 (*env)->ReleaseStringUTFChars(env, prompt, str);/*釋放*/

}

列印資訊在logcat中,就可以查看了。