色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          "); //-->

          博客專欄

          EEPW首頁 > 博客 > c語言宏定義##__VA_ARGS__封裝printf函數(shù),單片機(jī)實(shí)現(xiàn)簡單的分級(jí)日志模塊

          c語言宏定義##__VA_ARGS__封裝printf函數(shù),單片機(jī)實(shí)現(xiàn)簡單的分級(jí)日志模塊

          發(fā)布人:電子禪石 時(shí)間:2023-02-20 來源:工程師 發(fā)布文章

          在單片機(jī)開發(fā)中經(jīng)常需要加入printf之類的函數(shù)來輸出調(diào)試信息,這些信息一般伴隨著整個(gè)開發(fā)過程,但是在程序發(fā)布時(shí)候,又得將它們注釋掉,非常的不方便,于是有了以下解決辦法:


          使用宏定義開關(guān)

           #ifdef __DEBUG
           #define DEBUG(info)    printf(info)
           #else
           #define DEBUG(info)
           #endif

          但是這樣并不能發(fā)揮出printf函數(shù)的強(qiáng)大功能,使用起來并不方便。


          使用不定參數(shù)的宏定義


          c99規(guī)范后,編譯器就開始支持不定參數(shù)##__VA_ARGS__的宏定義

          相關(guān)知識(shí)可參考博客http://blog.csdn.net/aobai219/archive/2010/12/22/6092292.aspx

          于是我們就有了這樣的一個(gè)宏定義

          ————————————————

           #ifdef __DEBUG
           #define DEBUG(format, ...) printf (format, ##__VA_ARGS__)
           #else
           #define DEBUG(format, ...)
           #endif

          嗯,現(xiàn)在printf的功能是有了,那干脆再輸出一些相關(guān)的信息,這樣一下子就可以知道代碼位置,然后就變成這樣了:


           #ifdef __DEBUG
               #define DEBUG(format, ...) \
                    printf("FILE: "__FILE__", LINE: %d: "format"/n", __LINE__,##__VA_ARGS__)
           #else
               #define DEBUG(format, ...)
           #endif

          調(diào)試信息會(huì)按照下面格式輸出
          FILE: xxx, LINE: xxx, …….

          到這邊似乎都挺完美了,可還有一個(gè)問題,這邊的調(diào)試開關(guān)是全局的,可是有時(shí)候我們只關(guān)心某一模塊的調(diào)試信息,要是能屏蔽無關(guān)的信息那就好了,那我們?cè)僮鲆稽c(diǎn)功課,簡單的實(shí)現(xiàn)日志分級(jí),以下是代碼實(shí)現(xiàn):

          /*
           * logger.h
           *
           *  Created on: 2018年01月28日
           *      Author: dj666
           */
          
          #ifndef APP_PUBLIC_LOGGER_H_
          #define APP_PUBLIC_LOGGER_H_
          
          #define __DEBUG    //日志模塊總開關(guān),注釋掉將關(guān)閉日志輸出
          
          #ifdef __DEBUG
              #define DEBUG(format, ...) printf (format, ##__VA_ARGS__)
          #else
              #define DEBUG(format, ...)
          #endif
          
          //定義日志級(jí)別
          enum LOG_LEVEL {    
              LOG_LEVEL_OFF=0,
              LOG_LEVEL_FATAL,
              LOG_LEVEL_ERR,
              LOG_LEVEL_WARN,
              LOG_LEVEL_INFO,
              LOG_LEVEL_ALL,
          };
          
          #define log_fatal(level,format, ...) \
              do { \
                   if(level>=LOG_LEVEL_FATAL)\
                     DEBUG("\n->FATAL @ FUNC:%s FILE:%s LINE:%d \n" format "\n",\
                               __func__, __FILE__, __LINE__, ##__VA_ARGS__ );\
              } while (0)
          
          #define log_err(level,format, ...) \
              do { \
                   if(level>=LOG_LEVEL_ERR)\
                     DEBUG("\n->ERR   @ FUNC:%s FILE:%s LINE:%d \n" format "\n",\
                               __func__, __FILE__, __LINE__, ##__VA_ARGS__ );\
              } while (0)
          
          #define log_warn(level,format, ...) \
              do { \
                   if(level>=LOG_LEVEL_WARN)\
                     DEBUG("\n->WARN  @ FUNC:%s \n" format "\n",__func__, ##__VA_ARGS__ );\
              } while (0)
          
          #define log_info(level,format, ...) \
              do { \
                   if(level>=LOG_LEVEL_INFO)\
                     DEBUG("\n->INFO  \n"format"\n",##__VA_ARGS__ );\
              } while (0)
          
          #define log_debug(level,format, ...) \
              do { \
                   if(level>=LOG_LEVEL_ALL)\
                     DEBUG("\n->DEBUG \n"format"\n",##__VA_ARGS__ );\
              } while (0)
          
          #endif /* APP_PUBLIC_LOGGER_H_ */


          使用也非常簡單,定義一個(gè)局部的變量來保存該模塊的日志輸出級(jí)別,下面是使用示例:

          #include"logger.h"
          
          static enum LOG_LEVEL logger=LOG_LEVEL_WARN;//模塊日志輸出級(jí)別
          
          int main(void)
          { 
              logger = LOG_LEVEL_ALL; //修改模塊日志輸出級(jí)別
              log_debug(logger,"this is a debug");
              log_info(logger,"this is a info");
              log_warn(logger,"%s","this is a warn");
              log_err(logger,"this is a err %d ",-1);
          }


          c語言宏定義##__VA_ARGS__封裝printf函數(shù),單片機(jī)實(shí)現(xiàn)簡單的分級(jí)日志模塊_昵稱隨便取啦的博客-CSDN博客

          *博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。



          關(guān)鍵詞: c

          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉