接口
在一些设备类型定义中我们可以看到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?