Preface
关于为何需要使用device_class_set_parent_realize()
的讨论
1 | void device_class_set_parent_realize(DeviceClass *dc, |
从逆向device_class_set_parent_realize
的过程中探测到了一些QOM的设计哲学。
QOM系统的”对象构造”子系统
device_class_set_parent_realize()
是让用户方便的构造”realize
调用链”的API。因为用户自己定义的设备有自己的realize方法,需要将realize方法加入到QOM系统中,使用device_class_set_parent_realize()
就能方便的创建”继承关系的调用链”。
Q: QOM不是实现了OOP的继承会自己调用父类的”构造”方法吗?为何还要手动构造调用链?
A: QOM的继承仅仅能实现
instance_init
的调用链,而不能调用父类的realize
。这个根据TypeInfo
的定义可知。而且realize
是基于property系统(哈希表)的而不是基于TypeInfo
。而QOM系统中一个设备的构造是大致分为了object_initialize
,instance_init
和realize
三个部分的。所以需要手动构建realize
调用链。至于为何QOM会将设备实例化过程分解为三个部分后面章节进行讨论。
1 | struct TypeInfo |
对于任意设备的实例化方法xxx_realize
,基本都有如下的格式:
1 | void xxx_realize() { |
因此就会形成向上调用的调用链,会依据这样的结构依次向上对父类进行实例化。 而对于device_class_set_parent_realize()
1 | device_class_set_parent_realize(dc, ppc_cpu_realize, &pcc->parent_realize); |
总是会将dc->realize
设备”叶子设备”的realize。这样一来,dc->realize
就是设备realize过程的统一接口。调用dc->realize
后就会根据上述调用链调用父设备。
而为什么我觉得dc->realize
总是叶子设备的realize方法并作为统一接口呢,一来是device_class_set_parent_realize
的代码总是dc->realize=dev_realize
,二来是注释说TYPE_DEVICE
(即dc)是没有realize方法的,刚好可以留用作统一接口。
Since TYPE_DEVICE doesn’t implement @realize and @unrealize, types
derived directly from it need not call their parent’s @realize and
@unrealize.
For other types consult the documentation and implementation of the
respective parent types.
几种”构造函数”的区别
object_initialize
- TODO 未知
instance_init
realize
根据qdev-core.h
中注释的描述,我猜测,instance_init
似乎只是设置了一些初始值,这点和我们在OOP语言中对象实例(instance)一创建就会调用构造函数不同。
Trivial field initializations should go into #TypeInfo.instance_init.
Operations depending on @props static properties should go into @realize.
After successful realization, setting static properties will fail.
在QOM中对象真正的构造函数应该是realize
。即根据构造参数(depending on properties)执行构造函数: “Operations depending on @props static properties should go into @realize.”。不过看具体的realize
代码不是很能感受到这一点。e.g. ppc_cpu_realize
QOM将对象实例化过程分成了instance_init
和realize
两个阶段,instance_init
是在TypeInfo
中描述的会在object_new
时递归调用object_new_with_type
, object_init_with_type
等操作。而realize
是基于property(哈希表)的,需要在必要时人工realize
父设备(即有些设备虽然继承,但是是不需要realize
的)。见如下注释的说明:
Any type may override the @realize and/or @unrealize callbacks but needs
to call the parent type’s implementation if keeping their functionality
is desired. Refer to QOM documentation for further discussion and examples.
1 | static void object_init_with_type(Object *obj, TypeImpl *ti) |