在Android的c/c++代碼中使用LOG
在Android中,Java代碼通過android.util.Log輸出Log信息,同樣的本地c/c++代碼也提供了相對應而且是更多的接口。Android直接在頭文件(system/core/include/cutils/log.h)裏定義了一些日誌輸出的宏,這些宏比android.util.Log提供了更多的日誌輸出接口。因此,使用這些宏,就可以進行和java代碼中一樣的日誌輸出。宏LOGD(),LOGE(),LOGI(),LOGV(),LOGW(),LOGD()分別對應android.util.Log中的Log.d(),Log.e(),Log.i(),Log.v(),Log.w()。
注意:這裏的都是把日誌輸出到Main緩衝區。
log.h中對日誌輸出還提供一些更細的宏,比如對於LOGD(),還提供了LOGD_IF(),IF_LOGD(),SLOGD(),SLOGD_IF()。其中LOGD_IF()表示條件輸出,IF_LOGD()用於測試是否需要輸出,SLOGD()表示把日誌輸出到System日誌緩衝,SLOGD_IF()表示條件成立的情況下,把日誌輸出到System日誌緩衝。
注意:IF_LOGD()現在總是返回1.
因爲,LOG分了VERBOSE/DEBUG/INFO/WARN/ERROR/ASSERT等類別,簡單起見,以DEBUG爲例的實現來說明。
#ifndef LOGD
#define LOGD(...) LOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#endif
#ifndef LOGD_IF
#define LOGD_IF(cond, ...) \
( (CONDITION(cond)) \
? LOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__) \
: (void)0 )
#endif
#ifndef IF_LOGD
#define IF_LOGD() IF_LOG(LOG_DEBUG, LOG_TAG)
#endif
#ifndef SLOGD
#define SLOGD(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#endif
#ifndef SLOGD_IF
#define SLOGD_IF(cond, ...) \
( (CONDITION(cond)) \
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#endif
宏LOGD(),LOGE(),LOGI(),LOGV(),LOGW(),LOGD()其實最好後會使用以下的宏。
#ifndef LOG
#define LOG(priority, tag, ...) \
LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
#endif
#ifndef LOG_PRI
#define LOG_PRI(priority, tag, ...) \
({ \
if (((priority == ANDROID_LOG_VERBOSE) && (LOG_NDEBUG == 0)) || \
((priority == ANDROID_LOG_DEBUG) && (LOG_NDDEBUG == 0)) || \
((priority == ANDROID_LOG_INFO) && (LOG_NIDEBUG == 0)) || \
(priority == ANDROID_LOG_WARN) || \
(priority == ANDROID_LOG_ERROR) || \
(priority == ANDROID_LOG_FATAL)) \
(void)android_printLog(priority, tag, __VA_ARGS__); \
})
#endif
#define android_printLog(prio, tag, fmt...) \
__android_log_print(prio, tag, fmt)
而這一系列宏,最後還是調用了system/core/liblog/logd_write.c中的__android_log_print()
int __android_log_print(int prio, const char *tag, const char *fmt, ...)
{
va_list ap;
char buf[LOG_BUF_SIZE];
va_start(ap, fmt);
vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
va_end(ap);
return __android_log_write(prio, tag, buf);
}
這裏還是調到了函數__android_log_write()。__android_log_write()組織了參數,又調用了write_to_log這個函數指針。
要在c/c++中使用Log,很簡單。通常的做法是:
定義自己的TAG_LOG宏;包含頭文件log.h;然後在需要記錄Log的地方直接用LOGV/LOGD/LOGI/LOGW/LOGE等即可。
比如,文件lights.c中就在開頭這樣寫,
#define LOG_TAG "lights"
#include <cutils/log.h>
然後在該文件的後續部分,直接用LOGV/LOGE等來輸出日誌就可以。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.