vxworks源码剖析-对象篇(转)

来源:互联网 发布:志鸿优化网答案下载 编辑:程序博客网 时间:2024/06/16 20:03

当第一次看到vxworks的源码时,我才真正明白了怎么用C语言来实现面向对象的功能;以前虽然遇到过类似的文章,不过总是没有动力去了解实际的原理,这次闲来无事,拿到vxworks的源码,才看出一些端倪。

用c语言实现面向对象,其实是蛮难的,毕竟c语言是纯面向过程的语言,而面向过程和面向对象是两种完全不同的思想,虽不能说格格不入,但至少共同点甚少。不过,c语言天生具有的两大特性成就了其实现面向对象的功能,这就是结构体和指针。熟悉面向对象的朋友都应该知道类和结构体的异同,两者其实是很类似的,甚至可以 这样说,类就是在结构体的基础上衍生而来的,有了结构体后,实现面向对象就不是一句空话。大家都知道,类无非由两部分组成,属性和方法。属性就相当于结构体的域,而方法呢,在C语言中,可以用函数指针来实现,这样,类就构成了。

废话少说,看个示例:

typedef struct obj_class /* OBJ_CLASS */
    {
    OBJ_CORE objCore; /* object core of class object */
    struct mem_part *objPartId; /* memory partition to allocate from */
    unsigned objSize; /* 对象大小 */
    unsigned objAllocCnt; /* 已经分配的对象数目 */
    unsigned objFreeCnt; /* 已经释放的对象数目 */
    unsigned objInitCnt; /* 已经初始化的对象数目 */
    unsigned objTerminateCnt;/* 已经终结的对象数目 */
    int   coreOffset; /* offset from object start to objCore*/
    FUNCPTR createRtn; /* object creation routine */
    FUNCPTR initRtn; /* object initialization routine */
    FUNCPTR destroyRtn; /* object destroy routine */
    FUNCPTR showRtn; /* object show routine */
    FUNCPTR instRtn; /* object inst routine */
    } OBJ_CLASS;

上面这个结构体含有8个成员,5个函数指针,就相当于类的8个属性和5个方法;为了更加深入地了解obj_class,有必要说说各个成员的类型,首先来看看OBJ_CORE,这个类型也是一个结构体,它只包含一个类型为obj_class指针的域:

typedef struct obj_core /* OBJ_CORE */
    {
    struct obj_class *pObjClass; /* pointer to object's class */
    } OBJ_CORE;

相信大多数人应该已经猜到了obj_core的作用,如果没猜到也没关系,看到了后面的初始化函数以后相信大家都明白其作用了。接下来是objPartId,它是一个指向mem_part对象的指针,由于mem_part结构体十分复杂,而且后面会专门分析,因此本文暂不分析,大家只要知道这是一个结构体就可以了。最后一个值得说明的类型是FUNCPTR,使用过vxworks编程的朋友对这个类型肯定不会陌生,不过照顾所有人,还是将其定义描述一下:

typedef int   (*FUNCPTR) ();    /* ptr to function returning int */

描述完了obj_core的定义,下面看看与这个结构体相关的几个函数,函数不是很多,主要是对象创建、对象销毁函数,就相当于C++中的构造函数、析构函数一样,虽然对象创建、销毁最终还是调用obj_core结构体中定义的函数指针来实现的,但从这里,也可以看出,毕竟C语言不是面向对象的语言,要完全实现面向对象的功能,还是十分复杂的,需要借助一些辅助类来完成。说了半天,到底这些函数是什么呢?四个函数:classLibInit、classCreate、classInit和classDestroy(暂时未实现),另外还有一些相关的工具类函数这里就不细述了。上述四个函数(其实是三个函数)的关系可以用下图来表示:


classLibInit函数相当于class类的总类,用于初始化一个工具类对象;而classCreate则是实际的创建具体的对象的函数,其完成的工作,主要是两部分:内存分配和成员初始化。内存分配由objAlloc函数来实现,而成员初始化,则由classinit函数来实现。classInit函数就是具体的成员初始化函数,其职责很简单,将提供的参数赋值给obj_class的各个成员就足够了。上面曾经说过obj_core的作用,这里具体描述一下,在描述之前,先看看下面的代码:

STATUS classInit
    (
    OBJ_CLASS   *pObjClass,     /* pointer to object class to initialize */
    unsigned    objectSize,     /* size of object */
    int         coreOffset,     /* offset from objCore to object start */
    FUNCPTR     createRtn,      /* object creation routine */
    FUNCPTR     initRtn,        /* object initialization routine */
    FUNCPTR     destroyRtn      /* object destroy routine */
    )
    {

    /* default memory partition is system partition */

    略

    /* initialize object methods */

   略

    /* initialize class as valid object */

    objCoreInit (&pObjClass->objCore, classClassId);

    return (OK);
    }

void objCoreInit
    (
    OBJ_CORE    *pObjCore,      /* pointer to object core to initialize */
    OBJ_CLASS   *pObjClass      /* pointer to object class */
    )
    {
    pObjCore->pObjClass = pObjClass; /* validate object */
    pObjClass->objInitCnt ++;   /* keep track of object count */
    }
看完上面的代码以后,相应大多数人都会犯迷糊,因为有一个变量还没有介绍,这就是全局变量classClassId:

/* locals */

LOCAL OBJ_CLASS classClass;

/* globals */

CLASS_ID classClassId = &classClass;
从上面的classInit函数可以看出,只要是通过classCreate创建的对象,其objCore值都指向同一个变量,为什么要这样实现呢?这样实现的目的是为了便于实现类的标识。熟悉面向对象的朋友都知道,判断两个对象是否是同一个类太简单了,可以直接用==,或者用equals方法,或者自己定义一个compare方法,或者用getClass方法,但C语言里面比较只有地址值的比较,因此要实现类的标识相对就要困难一些。因此,这里定义了全局变量classClass,只要某个对象(obj_class变量)的objCore和classClass是相等的,那么它的类型就是obj_class(在vxworks中,类似的情形很多,例如标识文件的fpclass也是如此):

#define OBJ_VERIFY(objId,classId)      \
    (                                                                    \
      (          \
      (((OBJ_ID)(objId))->pObjClass == (struct obj_class *)(classId)) || \
       (         \
       ((OBJ_ID)(objId))->pObjClass &&      \
         (((OBJ_ID)(objId))->pObjClass ==                                \
        (CLASS_ID)(((struct obj_class *)(classId))->initRtn))     \
       )         \
      )                                                                  \
        ?                                                                \
            OK                                                           \
        :                                                                \
            (errno = S_objLib_OBJ_ID_ERROR, ERROR)                       \
    )

obj_class结构体是所有其他vxworks结构体最基础的部分,要弄懂vxworks的实现原理,这个结构体及内存分配机制必须明白。vxworks代码十分精致,本人功力有限,仅能分析到这个地步,不过相信只要持续不停地努力,迟早能领悟其精髓。


0
0
0

来自CSDN博客:http://blog.csdn.net/efan_linux/archive/2009/11/13/4804760.aspx