zoukankan      html  css  js  c++  java
  • 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)对象实例。
  • 相关阅读:
    IIS7.5解决应用程序池回收假死问题
    SQLServer跨库查询--分布式查询(转载)
    解决:System.Data.SqlClient.SqlError: FILESTREAM 功能被禁用
    Silverlight:telerik RadControls中RadGridView的一个Bug及解决办法(转载)
    list如何remove
    2015-11-18看的几篇文章,还没看完,先记录一下,回家看
    详解Android中AsyncTask的使用
    [Android] 随时拍图像处理部分总结及源码分享
    [Android] 通过GridView仿微信动态添加本地图片
    Android5.0以上系统的移动网络开关
  • 原文地址:https://www.cnblogs.com/danxi/p/5799513.html
Copyright © 2011-2022 走看看