0
点赞
收藏
分享

微信扫一扫

qemu源码分析(6)--Apple的学习笔记

1kesou 2023-09-18 阅读 30

一,前言

由于看到了类似的写法,都用到了object_dynamic_cast_assert函数,所以分析下。

二,源码分析

  1. 看到如下代码的写法,很眼熟

CortexMBoardState *board = CORTEXM_BOARD_STATE(machine);

machine 的类型是MachineState *

#define CORTEXM_BOARD_STATE(obj) \
 OBJECT_CHECK(CortexMBoardState, (obj), TYPE_CORTEXM_BOARD)
 
#define OBJECT_CHECK(type, obj, name) \
 ((type *)object_dynamic_cast_assert(OBJECT(obj), (name), \
 __FILE__, __LINE__, __func__))

  1. 展开后就是
    ((CortexMBoardState *)object_dynamic_cast_assert(((Object *)((machine))), ("cortexm:" "machine"), __FILE__, __LINE__, __func__))
  2. 主要分析object_dynamic_cast_assert函数

Object *object_dynamic_cast_assert(Object *obj, const char *typename,
 const char *file, int line, const char *func)
{
……
inst = object_dynamic_cast(obj, typename);
……
}
Object *object_dynamic_cast(Object *obj, const char *typename)
{
 if (obj && object_class_dynamic_cast(object_get_class(obj), typename)) {
 return obj;
 }
 
 return NULL;
}

  1. 所以最主要的是object_class_dynamic_cast函数

ObjectClass *object_class_dynamic_cast(ObjectClass *class,
 const char *typename)
{
……
  /* 根据name直接找class */
 type = class->type;
 if (type->name == typename) {
 return class;
   }
/* 根据name来找到Type */
target_type = type_get_by_name(typename);
 if (type->class->interfaces &&
 type_is_ancestor(target_type, type_interface)) {
 ……
}
/* 根据父类的name来找type */ 
else if (type_is_ancestor(type, target_type)) {
 ret = class;
 }
}

上面我加的注释其实描述的不对,应为用了找class,其实class是传入的参数,是通过object_get_class(obj)传入的obj->class,而object是应用层machine将类型MachineState*强转为object*的。所以这里不能说找class,只能说check class。所以从宏定义的名字OBJECT_CHECK也看出这个函数的含义是检查用的。

object_dynamic_cast的返回类型是Object*,能赋值给CortexMBoardState*吗?直接赋值不可以,但是右边的值强转为object*是可以的,因为CortexMBoardState的首个元素就是Object类型的对象。

若我不检查,直接CortexMBoardState *board = (Object *)machine来赋值也可以,但是若参数machine中的object不存在为Null那么就会存在问题,所以用了这个OBJECT_CHECK来封装。

三,小结

这种就类似c++中的基类转为派生类,说不定c++源码的实现也是这样的设计,又学习到一招,这就是我喜欢底层的原因,因为能更加深入的了解设计方法及运行机制。



举报

相关推荐

0 条评论