c语言入门容易,精通难,没个六七年的工作是不行的,所以我会把自己开发中认为精髓的东西,记录下来,以备后需。c语言作为我的本命语言,我觉着其中有很多有趣儿的地方。
c语言是典型的面向过程的语言,没有后来面向对象(OOP)中类,对象,继承,的概念,也就没有数据隐藏机制,但是聪明的人们总会想办法的,于是就有了黑盒模型。黑盒模型故名思议,盒子内部的实现细节对用户来说是不可见的,用户只能通过盒子提供的一个句柄(可以为void *或者int类型,具体实现比较灵活)来访问或者设置盒子内部的数据。
微软的windows操作系统,虽然是用c实现的,但是也采用了面向对象的设计思想,其中一部分就是通过黑盒来实现的。windows平台编程有个非常重要的概念——内核对象句柄(HANDLE),就是黑盒模型的典型代表。无论任何类型的内核对象(进程、文件、事件等等)都通过HANDLE句柄,获取或者设置对象的属性。不过不同windows版本,HANDLE的类型也不一致,有的时void *指针,有的是int类型(进程空间句柄表的索引)。
linux下的文件描述符FD(FileDescriptor)也是类似的实现。
为了演示黑盒模型,特意写了一个demo,linux平台下使用gcc -I./ -o demo -DLINUX demo.c 编译链接生成二进制可执行文件demo
头文件demo.h
-
#ifndef __DEMO_H
-
#define __DEMO_H
-
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
-
#if defined(WIN32) || defined(_WIN32)
-
#define STDCALL __stdcall
-
#elif defined(LINUX)
-
#define STDCALL
-
#else
-
#error "unspported platform"
-
#endif
-
-
typedef void * HOBJECT;
-
-
/* create an instance */
-
HOBJECT STDCALL create_object();
-
-
/* set value of specified field */
-
int STDCALL set_data(HOBJECT obj, int value);
-
-
/* get value of specified field, return default value def on error */
-
int STDCALL get_data(HOBJECT obj, int def);
-
-
/* delete object */
-
void STDCALL delete_object(HOBJECT obj);
-
-
#endif
函数、数据结构的定义demo.c
特别注意,设置对象数据成员值并返回旧数据成员值的函数
int set_data(HOBJECT obj, int value);采用的是连续三次异或运算,完成ptr->data与value的值交换,而非采用的第三方变量作为交换媒介的方式,这样做的优点,请参阅鄙人接下的博文。
-
include "demo.h"
-
-
typedef struct
-
{
-
int obj_id;
-
int data;
-
/* other data fields */
-
/* ... */
-
}object;
-
-
HOBJECT STDCALL create_object()
-
{
-
object *obj = (object *)malloc(sizeof(object));
-
if(obj != NULL)
-
{
-
memset((void *)obj, sizeof(object), 0);
-
/* object's id */
-
obj->obj_id = (int)obj;
-
return (HOBJECT)obj;
-
}
-
return NULL;
-
}
-
-
int set_data(HOBJECT obj, int value)
-
{
-
object *ptr=(object *)obj;
-
ptr->data ^= value;
-
value = ptr->data ^ value;
-
ptr->data ^= value;
-
return value;
-
}
-
-
int get_data(HOBJECT obj, int def)
-
{
-
return obj != NULL ? ((object *)obj)->data : def;
-
}
-
-
void delete_object(HOBJECT obj)
-
{
-
if(obj != NULL)
-
{
-
free(obj);
-
obj=NULL;
-
}
-
}
-
-
int main(int argc, char **argv)
-
{
-
/* entry point */
-
HOBJECT obj = create_object();
-
printf("old value:%d\n", set_data(obj, 1000));
-
printf("old value:%d\n", set_data(obj, 2000));
-
printf("attr:%d\n", get_data(obj, 100));
-
delete_object(obj);
-
-
return 0;
-
}
当然真正的项目中,实现也会相对比较复杂,相对于java这类语言(很多底层的东东对程序猿都是透明的),对象的内存管理就得自己考虑。生产环境对象分配是不可以用malloc的,这样会产生大量的内存碎片,比较推荐的是linux内核的slab内存分配机制,或者使用开源的内存管理库,当然有特殊需求,也可以自己设计内存管理算法。
阅读(1035) | 评论(0) | 转发(0) |