概述
PJSIP LOG篇
- PJSIP LOG篇
- log.h
- log.c
- 总结
PJSIP LOG篇
PJSIP内置log的模块,该模块可以自行定制,设计的十分灵活。
本次分析设计到的文件如下:
├── log.c
├── log_writer_printk.c
└── log_writer_stdout.c
log.h
使用枚举定义日志输出的内容里面包含的东西。
enum pj_log_decoration{...}
##:是字符串连接,如果调用为PJ_LOG(1,"hello world")
,则实际调用为pj_log_wrapper_1("hello world")
PJ_LOG(level,arg) pj_log_wrapper_##level(arg)
该函数是 自定义重写函数的核心,只需要重新实现该函数,然后调用pj_log_set_log_func
,将重新实现的函数传入进去,便可以进行函数重写。
typedef void pj_log_func(int level, const char *data, int len);
该函数可以用来控制PJSIP打印日志的等级,即:6=very detailed..1=error only, 0=disabled
,可以在初始化该库之前进行调用。
PJ_DECL(void) pj_log_set_level(int level);
该函数用来控制输出
PJ_DECL(void) pj_log_set_decor(unsigned decor);
该宏很有意思,他用编译参数宏PJ_LOG_MAX_LEVEL
来控制相关函数是否实现,如果PJ_LOG_MAX_LEVEL=0
也就相当于所有的日志都不用打印了,也就没有必要实现这些函数了,用define将这些函数定义为空,减少了编译库的大小。
#if PJ_LOG_MAX_LEVEL >= 1
PJ_DECL(void) pj_log(const char *sender, int level,
const char *format, va_list marker);
pj_log_get_log_func(void);
#else
define pj_log_set_log_func(func)
define pj_log_set_level(level)
define pj_log_set_decor(decor)
#endif
和上述的宏类似,如果PJ_LOG_MAX_LEVEL为0,则将pj_log_wrapper_1
写为空实现。
#if PJ_LOG_MAX_LEVEL >= 1
#define pj_log_wrapper_1(arg) pj_log_1 arg
/** Internal function. */
PJ_DECL(void) pj_log_1(const char *src, const char *format, ...);
#else
#define pj_log_wrapper_1(arg)
#endif
log.c
该全局变量为外部掉用pj_log_set_level
设置下来的等级,用来在程序运行时候控制PJSIP打印日志的等级。
static int log_max_level = PJ_LOG_MAX_LEVEL;
该函数是用来打印日志输出的函数。
static pj_log_func *log_writer = &pj_log_write;
该函数是所有等级的函数最终都会调入该函数的。
PJ_DEF(void) pj_log( const char *sender, int level,
const char *format, va_list marker)
{
//...
if (log_writer)
(*log_writer)(level, log_buffer, len);
//...
}
log_writer则是最终输出的函数,在原本的项目中有log_writer_printk.c
, log_writer_stdout.c
分别定义了该函数,而PJSIP则根据不同平台使用不同的实现,进行打印。
总结
- 该模块的宏定义是值得学习的,利用宏定义巧妙地在预处理阶段,将不需要的代码给删除掉,节省了代码段空间。
- 作为一个三方库,考虑的是十分周到了,利用
pj_log_set_log_func
来巧妙的让使用者自己控制日志怎么输出,考虑的十分周全。
一点拙见,欢迎交流。
最后
以上就是舒适书本为你收集整理的01. PJSIP LOG篇PJSIP LOG篇的全部内容,希望文章能够帮你解决01. PJSIP LOG篇PJSIP LOG篇所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复