本文主要介绍pjlib的基本特性
1.PJLIB是什么?
pjlib是用于构建可扩展的应用程序,基于C开发的开源的,较小footprint的架构库.由于他具有较小的footprintf,其可以应用到嵌入式应用程序中,同时基于pjlib也可以构建高性能的协议栈.
2.下载
PJLIB以及所有的文档都可以在http://www.pjsip.org上获得.
3.PJLIB特性
PJLIB为完全开源的,其遵循GPL许可,用户可以基于其制定自己的许可.
3.1极强的可移植性
PJLIB本身就被设计成具有极强的移植性.其几乎可以运行在任何一款CPU处理器(16-bit, 32-bit, 或者 64-bit,大端或小端,多任务或单任务处理器)
和操作系统之上,支持/不支持浮点数,支持/不支持多线程,其甚至可以运行在没有ANSI LIBC库的环境之上.
PJLIB目前支持的平台如下:
Win32/x86 (Win95/98/ME, NT/2000/XP/2003, mingw).
arm, WinCE and Windows Mobile.
Linux/x86, (user mode and as kernel module(!)).
Linux/alpha
Solaris/ultra.
MacOS X/powerpc
RTEMS (x86 and powerpc).
3.2较小的软件规模
对于特殊的嵌入式应用而言,较小的库规模是一个主要的要求.作为一个粗略的介绍,我们基本上将库的大小控制在
100KB之下.其实,PJLIB的绝大多数功能都可以按照特殊的应用场景进行定制裁剪;用户可以使能/禁用某项特殊的功能
使软件的规模大小,软件系统,功能达到平衡.
3.3较高的性能
PJLIB尽力设计成与特殊平台无关的高性能软件框架.
3.4杜绝动态内存分配
为了能够使应用运行的足够块,PJLIB绝不会使用malloc(),其都实在预先分配的内存池中获取内存.
该机制具有一下几个优势:
1.alloc()的复杂度为O(1)
2.alloc()不需要互斥操作.我们假设同步在更高层进行维护.
3.不需要free()操作.所有内存块都会在内存池销毁时释放.
3.5抽象操作系统特性
PJLIB抽象了不具备可移植性的操作系统特性如下:
1.线程
可移植的线程管理机制
2.线程本地存储
基于线程私有数据机制实现数据存储
3.互斥保护
互斥访问区保护
4.信号量
5.原子变量
提供原子变量定义和相关操作
6.临界区
高效的临界区访问机制
7.锁对象
高级锁抽象,其将所有锁都抽象为lock objects,可谓基于C开发的OO锁模板
8.事件对象
9.时间对象和管理
可移植的时间管理对象
10.高精确度的时间戳
等等
3.6低级别的网络I/O处理能力
PJLIB对于网关I/O通信,具有非常强的可移植抽象以及非常完备的API.PJLIB提供如下功能:
1.Socket抽象
高级的socket抽象,支持 standard BSD socket, Windows socket, Linux kernel socket, PalmOS networking API,等.
2.NAT功能
可移植的NAT功能,例如实现了pj_gethostbyname().
3.Socket select() API
可移植的select实现,例如pj_sock_select()
3.7定时器管理
PJLIB实现了一个基于heap的被动的定时器管理机制.
数据结构
1.字符串处理
2.数组
3.哈希表
4.链表
5.RB 平衡树
3.8异常构造
TRY/CATCH机制用于捕获程序异常,内存池和词法分析工具中默认使用该技术.其使用方式如下:
#define SYNTAX_ERROR 1
PJ_TRY {
msg = NULL;
msg = parse_msg(buf, len);
}
PJ_CATCH ( SYNTAX_ERROR ) {
.. handle error ..
}
PJ_END;
3.9日志管理
PJLIB日志管理模块能够使应用程序的日志输出到不同设备中.基本特性如下:
1.日志内容在编译和运行时调节
2.输出设备可配置(stdout, printk,file,等)
3.日志属性可配置
随机数据和GUID生成机制
PJLIB提供了随机的字符串(pj_create_random_string()),或者全局唯一标示符生成函数
3.10配置使用PJLIB
1.按照程序安装手册进行PJLIB的配置和安装
2.在应用程序中使用pjlib
包含pjlib.h头文件,或者包含特殊的头文件
#include <pjlib.h>
#include <pj/log.h>
#include <pj/os.h>
库文件路径,我们可以使用静态或动态连接的形式使用pilib库
Principles in Using PJLIB
4.PJLIB使用准则:
4.1调用pj_init()
使用PJLIB做任何事情之前必须调用pj_init.pj_init会确保PJLIB系统正常启动.
4.2杜绝使用ANSI C
可能与我们之前的认识有所不同,ANSI C(或者LIBC)并不是极具移植性的库,也不是应用最为广泛的库.例如,LIBC
并不能适用于linux kernel.通常,LIBC在RTOS系统中都会被重新裁剪以减少软件的规模.所以,为了获得较大的可
移植性,杜绝使用ANSI C.应用程序中甚至都不能包含除了<include/pj>意外的外部库文件.PJLIB提供的函数功能足
以保证我们的应用程序的功能.
4.3使用pj_str而不是 C 字符串
PJLIB 使用pj_str_t替换通常的C字符串完成字符串相关的操作.使用者应该同样遵循该原则.记住,ANSI string-h
提供的字符串功能不总是可以获取的,并且PJLIB string 更加高效.
4.4使用内存池完成内存管理
杜绝使用一切malloc以及其同族函数完成应用程序的内存管理.使用PJLIB FAST Memory Pool.其更加高效和高可移植
性.
4.5使用日志系统完成文本信息的输出
杜绝使用stdio.h输出文本信息.使用PJLIB日志工具进行文本输出.