接口

在一些设备类型定义中我们可以看到interfaces一栏。

static TypeInfo pc_dimm_info = {
    .name          = TYPE_PC_DIMM,
    .parent        = TYPE_DEVICE,
    ...
    .interfaces = (InterfaceInfo[]) {
        { TYPE_MEMORY_DEVICE },
        { }
    },
};

那这一栏是什么意思呢?让我们来进一步打开看看。

Interface也是一种类型

进一步看,可以发现在Qemu模型中接口也是一种类型,并且也有父子关系。

static TypeInfo interface_info = {
    .name = TYPE_INTERFACE,
    .class_size = sizeof(InterfaceClass),
    .abstract = true,
};

static const TypeInfo memory_device_info = {
    .name          = TYPE_MEMORY_DEVICE,
    .parent        = TYPE_INTERFACE,
    .class_size = sizeof(MemoryDeviceClass),
};

但是和普通类型不同,他们只有对应的Class,而没有object。

我们尝试把这两个类型画成图,或许能看得更清楚一些。

接口类型附属于设备类型

接口类型是一个很有意思的类型,刚才我们看到了TYPE_MEMORY_DEVICE会对应有一个MemoryDeviceClass。

对于普通的设备类型,那整个系统中就只会有这么一个对应的Class,但是接口类型则不是。

还是从代码上来看:

对于定义了interfaces成员的类型,在初始化中将通过type_initialize_interface来创建自己的接口类型。 而这个类型不仅在系统中注册,还会添加到class->interfaces链表上。

希望这个图能够对理解接口有一点点帮助。

设置接口类型的“虚函数”

接口类型重要的成员就是它的虚函数了,那谁在什么时候设置呢?

因为接口类型是从属于设备类型的,所以虚函数的设置在设备类型初始化函数中设置。

对于pc-dimm设备,这个函数就是pc_dimm_class_init中了。

从设备类型到接口类型

在上面这段代码中有一个有意思的地方就是怎么从设备类型PC_DIMM_CLASS转换到接口类型MEMORY_DEVICE_CLASS的

让我们来看一眼:

经过这两个宏,最后会落到函数object_class_dynamic_cast()。

而这个函数就是沿着klass->interfaces链表查找名字为TYPE_MEMORY_DEVICE的类型。如果找到了唯一的,那就范围它。

怎么样,现在是不是能看清楚这个函数的意义,以及设备类到接口类的转换了?

Last updated

Was this helpful?