一,前言
最近从main开始看了opt参数相关的解析,这个比较简单我就不写了,然后当时我搞不清楚的是MachineClass和TypeImpl类的关系。本节主要分析的其实就是分析machine_class怎么来的,其实也就是machine_class = select_machine();
二, 源码分析
- 关于mc的来历type_initialize中ti->class->type = ti;
另外一个特点是MachineClass的第一个地址内容是ObjectClass,之后会用上。
- 利用非NULL进行归递搜索的方法通过归递来搜索父类
static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type)
{
assert(target_type);
/* Check if target_type is a direct ancestor of type */
while (type) {
if (type == target_type) {
return true;
}
type = type_get_parent(type);
}
return false;
}
一层层读取父类
static TypeImpl *type_get_parent(TypeImpl *type)
{
if (!type->parent_type && type->parent) {
type->parent_type = type_get_by_name(type->parent);
g_assert(type->parent_type != NULL);
}
return type->parent_type;
}
在ObjectClass *object_class_dynamic_cast(ObjectClass *class,const char *typename)函数中 type = class->type;
if (type->name == typename) {
return class;
}
通过type值对比找typeImpl实体。感觉设计的不太直接,先找class,然后class又指向typeImpl。直接对比2个typeImpl不好吗?可能为了函数复用吧,所以打包了这个函数。
若不是直接为machine那么就搜索其父类TypeImpl。如item2的代码就是搜索父类。
- 继续说find_default_machine函数。
MachineClass *find_default_machine(void)
{
GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
。。。
}
object_class_get_list会返回GSList类型
GSList *object_class_get_list(const char *implements_type,
bool include_abstract)
{
GSList *list = NULL;
object_class_foreach(object_class_get_list_tramp,
implements_type, include_abstract, &list);
return list;
}
所以只要查data->opaque什么时候赋值的,就是GSList的值了。
进入这个fn,其实就是为GLlist中的data赋值为这个找到的class
G_slist_prepend是在链表头追加内容,通过归递又找到了一个父类是machine的,所以也加入了链表中
- 关于MachineClass
objectClassMachineClass *mc = MACHINE_CLASS(oc);
关于mc地址和oc首地址成员一样,但是里面其它值什么时候赋值的呢!原来type_init归递的时候都赋值了。
所以如下el->data虽然是一个objectclass,但是也是一个MachineClass,因为首地址一样。但是由于temp->is_default=0所以最终返回的mc是NULL。
MachineClass *find_default_machine(void)
{
GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
MachineClass *mc = NULL;
for (el = machines; el; el = el->next) {
MachineClass *temp = el->data;
if (temp->is_default) {
mc = temp;
break;
}
}
g_slist_free(machines);
return mc;
}
最后根据boardName找到了mc。如下函数的写法和之前分析的根据is_default的查找方法雷同。只是在GSList中对比的是name而已。
static MachineClass *find_machine(const char *name)
{
GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
MachineClass *mc = NULL;
for (el = machines; el; el = el->next) {
MachineClass *temp = el->data;
if (!strcmp(temp->name, name)) {
mc = temp;
break;
}
if (temp->alias &&
!strcmp(temp->alias, name)) {
mc = temp;
break;
}
}
g_slist_free(machines);
return mc;
}
三,小结
所以主要内容就是TypeImpl关联到了ObjectClass,而MachineClass中包含ObjectClass,然后就联系起来了。有时候想想c代码设计的核心就是数据结构+算法,而这里所谓的算法就是递归搜索判断而已。不同的数据结构就要搭配不同的算法了,这里就要考虑怎么样的数据结构才是最优化的。
标签:el,Apple,mc,Qemu,源码,temp,MachineClass,type,class From: https://blog.51cto.com/u_16247275/7483657