C/C++编程-理论学习-考鼎录<子驱动程序>

子驱动程序

  • 子驱动程序模式在稍有程序规模的C项目中大量应用
  • 子驱动程序模式的一般实现套路
    • 进一步考虑
    • 正确区分机制和策略
      • MINIGUI中的逻辑字体

子驱动程序模式在稍有程序规模的C项目中大量应用

  1. Uinx一切皆文件
  2. Unix/Linux
  3. MiniGUI识别、应用不同的图片格式

注:一个统一的接口,下面有有不同的实现内容。

子驱动程序模式的一般实现套路

  1. 一套聚类接口
  2. 一些公共数据组成的抽象对象(数据结构)
  3. 一组函数指针组成的操作集(数据结构)
  4. 针对不同子类的操作集实现
/* STDIO接口的实现 */
struct _file_obj;
typedef struct _file_obj file_obj;

struct _file_ops {
	file_obj *open(void *pathname_buf, size_t size, const char xx);
	ssize_t read(file_obj *file, void *buf, size_t count);
	ssize_t write(file_obj *file, const void *buf, size_t count);
	off_t lseek(file_obj *file, off_t offset, int whence);
	void close(file_obj *file);
};

struct _FILE;
typedef struct _FILE FILE;


/* FILE结构:基本设计 */
struct _FILE{

};

/**
* fopen 的实现 
* /
struct _file_obj{
	int fd;
}


/* fmemopen 的实现 */
struct _file_obj{
	void*			buf;
	size_t			size;
	unsigned int	flags;
	off_t			rw_pos;
};

static file_obj *mem_open(void *buf, size_t size, const char xxx)
{
	...
}

static struct _file_ops mem_file_ops = {
	open: mem_open;
	...
}

FILE *fmemopen(void *buf, size_t size, const char *mode)
{
	FILE *file = NULL;
	
	file_obj *obj = mem_open(buf,size,mode);
	if(obj)
	{
		file = calloc(1, sizeof(FILE));
		file.obj = obj;
		file.ops = file_file_ops;
	}
	return file;
}

进一步考虑

  1. STDIO是带有缓冲区功能的,缓冲区信息应该在FILE中维护还是在file_obj中维护?
  2. 当前读写位置在什么地方维护?
  3. 子驱动程序设计的关键点
    1. 抽象对象的数据结构如何确定?
    2. 操作集如何取舍?

正确区分机制和策略

  • 机制:需要提供什么功能
  • 策略:如何使用这些功能
  • 以STDIO实现为例:
    1. 带有缓冲区支持的格式化输入输出属于使用策略,对不同类型的文件对象是一样的。
    2. 文件操作集提供的就是机制,符合最小的完备集合原则。

注:锤子的机制:【把】长、轻、韧(增加力矩,便于挥动);【头】硬,重,造型(便于敲击,释放力量);
锤子的策略:1. 可以用来砸钉子;2. 可以用来转圈着砸,安装于机器上; 3,可以放到机器人手里,然后给机器人下指令;
4,可以只小幅度挥动;5.等等;
综上,可见机制是更适合底层驱动实现,策略更符合上层应用实现。所以,对抽象的数据结构,操作集合都可依据此做判断,是放到驱动层,还是应用层。

MINIGUI中的逻辑字体

  • 现代图形系统中文字的显示过程:
    1. 字符串解码取出一个个字符。
    2. 如果包含有复杂书写(如阿拉伯、希伯来、印度语系文字),需要做双向排版处理。
    3. 字符到字型:如果含有复杂书写文字,需要做字符成型(shaping)处理,比如组合字符问题。
    4. 从字体文件中获取自型信息(点阵或矢量)。
    5. 交由图形系统渲染字型到指定的缓冲区位置。
/* 主要接口 */
PLOGFONT CreateLogFontByName(const char* font_name);
void GUIAPI DestroyLogFont (PLOGFONT log_font);

PLONGFONT GUIAPI SelectFont (HDC hdc, PLONGFONT log_font);
int GUIAPI TextOutLen (HDC hdc, int x, int y,const char* spText, int xxx);

......
- 抽象字符集
- 转化为unicode
- 排版操作
/* LOGFONT */
struct _DEVFONT;
typedef struct _DEVFONT DEVFONT;

typedef struct _LOGFONT{
	char* type;
	char* family;
	char* charset;
	DWORD32 style;
	int size;
	int rotation;
....

	unsigned short scales[MAXNR_DEVFONTS];
	DEVFONT*		devfonts[MAXNR_DEVFONTS];
}LOGFONT;


struct DEVFONT
{
	char name[ MAX +1 ];

	...
	FONTOPS* font_ops;
	CHARSETOPS* charset_ops;
	....
}


struct _CHARSETOPS
{
	int nr_chars;
	int bytes_maxlen_char;	
	const char* name;
	....
	int (*len_first_char)(const unsigned char * mstr, int mst,xxx);
	Achar32(*get_char_value)(const unsigned char * xxxx, xxxx);
	// 一堆函数
}

你可能感兴趣的:(嵌入式,C/C++编程,理论指导,c语言,c++,学习)