嵌入式C代码日志框架

在C代码的日常调试或者测试过程中,常常需要通过打印来输出代码运行过程中的一些状态,以便了解程序运行过程中到底进行了什么样的动作,因而在整个项目中将会存在大量日志输出的操作,而正式工程的输出并不需要这些。在发布正式程序时需要屏蔽这些操作,而在调试时又需要打开这些代码。通过宏定义能够快速注释和取消注释,但是会存在大量的判断语句。

本文将通过可变参函数的方式实现这种日志管理,以printf打印输出为例:

#include <stdio.h>
#include <stdarg.h>
#include <string.h>

使用可变参函数,需要包含stdarg.h头文件

在调试测试过程中,不同的情况下可能需要不同的打印输出,创建一个打印等级来控制打印的需求,创建一个宏作为日志打印的选择开关,对日志打印函数作一次封装,对日志打印函数所在位置的函数名和行号进行输出。使用__VA_ARGS__特殊形参表示可变参数的宏,否则vs无法正常传递参数。

#define EM_Log(level,...) EM_LOG(level,__FUNCTION__,__LINE__,__VA_ARGS__)
#define OPEN_LOG 1

typedef enum
{
	DEBUG = 0,
	WARNING,
	ERROR,
}EN_ALMLEVEL_T;

日志打印函数包含等级和打印数据两个输入

void EM_LOG(EN_ALMLEVEL_T level,char * function,int line, char *fmt, ...)
{
	#ifdef OPEN_LOG
		va_list  arg;
		va_start(arg, fmt);
		char *buff = (char *)malloc((vsnprintf(NULL,0,fmt,arg)+1) * sizeof(char));
		vsnprintf(buff, strlen(buff),fmt, arg);
		va_end(arg);
		if (DEBUG <= level)
		{
			printf("[%s] [%s %d] %s\n", Get_Alm_Level(level), function, line, buff);
		}
	#endif // OPEN_LOG
}

定义一个buff用来存储list,使用vsnprintf函数当输出指针为NULL时返回返回list变量占用内存大小。创建一个日志等级的函数获取不同日志等级时对应的字符输出

char * Get_Alm_Level(const int level)
{
	if (DEBUG == level)
	{
		return "debug!";
	}
	else if (WARNING == level)
	{
		return "Warning!";
	}
	else if (ERROR == level)
	{
		return "error!";
	}
}

函数调用即可正常进行日志打印:

void main()
{
	char a = 1;
	EM_LOG(DEBUG, __FUNCTION__, __LINE__, "%s %s","app_start","note!");
	EM_Log(DEBUG, "%s %d", "A =", a);
}

结果如下:

[debug!] [main 63] app_start note!
[debug!] [main 64] A = 1
请按任意键继续. . .

通过OPEN_LOG宏定义实现日志打印选择,通过日志等级设定选择输入想要打印的日志,省去了代码调试和发布之间代码注释和取消注释的工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值