• 在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缓冲区。
    另外,关于此文最好对照着《Android LOG机制流程图》一起来看。
    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这个函数指针。
    关于write_to_log这个函数指针的调用详情请参考《Android中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等来输出日志就可以。
  • 相关阅读:
    ASP.NET MVC 重点教程一周年版 第二回 UrlRouting
    ASP.NET MVC 重点教程一周年版 第三回 Controller与View
    DynamicData for Asp.net Mvc留言本实例 下篇 更新
    Asp.net MVC视频教程 18 单选与复选框
    使用ASP.NET MVC Futures 中的异步Action
    ASP.NET MVC RC 升级要注意的几点
    ATL、MFC、WTL CString 的今生前世
    msvcprt.lib(MSVCP90.dll) : error LNK2005:已经在libcpmtd.lib(xmutex.obj) 中定义
    关于Windows内存的一些参考文章
    Windows访问令牌相关使用方法
  • 原文地址:https://www.cnblogs.com/liyuzhao/p/3818209.html
Copyright © 2020-2023  润新知