• libvirt里的面向对象的C语言


    C语言:类的声明和定义


     1 // 通用父类的定义
     2 struct _virClass {
     3     virClassPtr parent;
     4 
     5     unsigned int magic;
     6     char *name;
     7     size_t objectSize;
     8 
     9     virObjectDisposeCallback dispose;
    10 };
    11 typedef struct _virClass virClass;
    12 typedef virClass *virClassPtr;
    13 
    14 //通用对象的定义
    15 struct _virObject {
    16     /* Ensure correct alignment of this and all subclasses, even on
    17      * platforms where 'long long' or function pointers have stricter
    18      * requirements than 'void *'.  */
    19     union {
    20         long long dummy_align1;
    21         void (*dummy_align2) (void);
    22         struct {
    23             unsigned int magic;
    24             int refs;
    25         } s;
    26     } u;
    27     virClassPtr klass;
    28 };
    29 
    30 struct _virObjectLockable {
    31     virObject parent;
    32     virMutex lock;
    33 };
    34 
    35 // 各个子类的声明与类对象指针的实例化
    36 static int
    37 virDataTypesOnceInit(void)
    38 {
    39 #define DECLARE_CLASS_COMMON(basename, parent)                   
    40     if (!(basename ## Class = virClassNew(parent,                
    41                                           #basename,             
    42                                           sizeof(basename),      
    43                                           basename ## Dispose))) 
    44         return -1;
    45 #define DECLARE_CLASS(basename)                                  
    46     DECLARE_CLASS_COMMON(basename, virClassForObject())
    47 #define DECLARE_CLASS_LOCKABLE(basename)                         
    48     DECLARE_CLASS_COMMON(basename, virClassForObjectLockable())
    49 
    50     DECLARE_CLASS_LOCKABLE(virConnect);
    51     DECLARE_CLASS_LOCKABLE(virConnectCloseCallbackData);
    52     DECLARE_CLASS(virDomain);
    53     DECLARE_CLASS(virDomainSnapshot);
    54     DECLARE_CLASS(virInterface);
    55     DECLARE_CLASS(virNetwork);
    56     DECLARE_CLASS(virNodeDevice);
    57     DECLARE_CLASS(virNWFilter);
    58     DECLARE_CLASS(virSecret);
    59     DECLARE_CLASS(virStream);
    60     DECLARE_CLASS(virStorageVol);
    61     DECLARE_CLASS(virStoragePool);
    62 
    63     DECLARE_CLASS_LOCKABLE(virAdmConnect);
    64     DECLARE_CLASS_LOCKABLE(virAdmConnectCloseCallbackData);
    65     DECLARE_CLASS(virAdmServer);
    66     DECLARE_CLASS(virAdmClient);
    67 
    68 #undef DECLARE_CLASS_COMMON
    69 #undef DECLARE_CLASS_LOCKABLE
    70 #undef DECLARE_CLASS
    71 
    72     return 0;
    73 }
    74 //定义这些指针的用途就是后续需要创建子类的对象是作为类型参数传入,用来区分不同的对象实例。同时,也是最主要的,指定了子类的对象的内存分配大小。

    C语言:按一个对象类型来new一个对象实例


     1 // 类似C++的new操作运算符。oh, my gold!
     2 void *virObjectNew(virClassPtr klass)
     3 {
     4 // 声明父类指针,多态的开始么。。。
     5     virObjectPtr obj = NULL;
     6 // VIR_ALLOC_VAR 分配的内存大小为子类大小,指针的起始位置指向父类对象。
     7     if (VIR_ALLOC_VAR(obj,
     8                       char,
     9                       klass->objectSize - sizeof(virObject)) < 0)
    10         return NULL;
    11 // 因为是C语言,所以需要手动初始化父类信息,magic指明这个子类跟父类是同一类
    12     obj->u.s.magic = klass->magic;
    13     obj->klass = klass;
    14     virAtomicIntSet(&obj->u.s.refs, 1);
    15 
    16     PROBE(OBJECT_NEW, "obj=%p classname=%s", obj, obj->klass->name);
    17 
    18     return obj;
    19 }
    20 // 如此,可以看一个子类的声明和分配例子:
    21 virStreamPtr virGetStream(virConnectPtr conn)
    22 {
    23     virStreamPtr ret = NULL;
    24 
    25     if (virDataTypesInitialize() < 0)
    26         return NULL;
    27 
    28     if (!(ret = virObjectNew(virStreamClass)))
    29         return NULL;
    30 
    31     ret->conn = virObjectRef(conn);
    32     return ret;
    33 }
    34 
    35 struct _virStream {
    36     virObject object;
    37     virConnectPtr conn;
    38     unsigned int flags;
    39 
    40     virStreamDriverPtr driver;
    41     void *privateData;
    42 };
    43 typedef struct _virStream virStream;
    44 typedef virStream *virStreamPtr;
    45 
    46 //当调用 virObjectNew(virStreamClass)的时候,virStreamClass的objectsize在CLASS_NEW的时候已经设置为sizeof(virStream)
    47 //所以最后得到一个正确的(* virStreamPtr)对象实例。
  • 相关阅读:
    在IDEA(phpStorm)中使用Babel编译ES6
    vue2.0使用记录
    透过一道面试题来探探JavaScript中执行上下文和变量对象的底
    详解Object.constructor
    javascript数组操作
    项目协作
    关于@BindingResult bindingresult...
    在Java中使用Jedis的测试案例
    数据库性能优化之SQL语句优化(转 java知音)
    SpringBoot之集成Spring AOP
  • 原文地址:https://www.cnblogs.com/danxi/p/5799513.html
Copyright © 2020-2023  润新知