接前一篇文章: QEMU源码全解析37 —— Machine(7)
本文内容参考:
《 QEMU /KVM》源码解析与应用 —— 李强,机械工业出版社
特此致谢!
上一回经过了重重周折,终于找到了MACHINE的定义所在:
OBJECT_DECLARE_TYPE(MachineState, MachineClass, MACHINE)
本回就详细解析一下这段代码。别看代码只有一行,内容还是蛮多的。
OBJECT_DECLARE_TYPE是一个宏,在include/qom/object.h中定义,代码如下:
- /**
- * OBJECT_DECLARE_TYPE:
- * @InstanceType: instance struct name
- * @ClassType: class struct name
- * @MODULE_OBJ_NAME: the object name in uppercase with underscore separators
- *
- * This macro is typically used in a header file, and will:
- *
- * - create the typedefs for the object and class structs
- * - register the type for use with g_autoptr
- * - provide three standard type cast functions
- *
- * The object struct and class struct need to be declared manually.
- */
- #define OBJECT_DECLARE_TYPE(InstanceType, ClassType, MODULE_OBJ_NAME) \
- typedef struct InstanceType InstanceType; \
- typedef struct ClassType ClassType; \
- \
- G_DEFINE_AUTOPTR_CLEANUP_FUNC(InstanceType, object_unref) \
- \
- DECLARE_OBJ_CHECKERS(InstanceType, ClassType, \
- MODULE_OBJ_NAME, TYPE_##MODULE_OBJ_NAME)
这里边又涉及到两个宏:G_DEFINE_AUTOPTR_CLEANUP_FUNC和DECLARE_OBJ_CHECKERS。重点关注后一个。
DECLARE_OBJ_CHECKERS宏实际上就在OBJECT_DECLARE_TYPE宏的上边,代码如下:
- /**
- * DECLARE_OBJ_CHECKERS:
- * @InstanceType: instance struct name
- * @ClassType: class struct name
- * @OBJ_NAME: the object name in uppercase with underscore separators
- * @TYPENAME: type name
- *
- * Direct usage of this macro should be avoided, and the complete
- * OBJECT_DECLARE_TYPE macro is recommended instead.
- *
- * This macro will provide the three standard type cast functions for a
- * QOM type.
- */
- #define DECLARE_OBJ_CHECKERS(InstanceType, ClassType, OBJ_NAME, TYPENAME) \
- DECLARE_INSTANCE_CHECKER(InstanceType, OBJ_NAME, TYPENAME) \
- \
- DECLARE_CLASS_CHECKERS(ClassType, OBJ_NAME, TYPENAME)
这里边又包含了DECLARE_INSTANCE_CHECKER和DECLARE_CLASS_CHECKERS两个宏定义。打破砂锅问到底,看看这两个宏的代码,实际上就在DECLARE_OBJ_CHECKERS宏的上边。
- /**
- * DECLARE_INSTANCE_CHECKER:
- * @InstanceType: instance struct name
- * @OBJ_NAME: the object name in uppercase with underscore separators
- * @TYPENAME: type name
- *
- * Direct usage of this macro should be avoided, and the complete
- * OBJECT_DECLARE_TYPE macro is recommended instead.
- *
- * This macro will provide the instance type cast functions for a
- * QOM type.
- */
- #define DECLARE_INSTANCE_CHECKER(InstanceType, OBJ_NAME, TYPENAME) \
- static inline G_GNUC_UNUSED InstanceType * \
- OBJ_NAME(const void *obj) \
- { return OBJECT_CHECK(InstanceType, obj, TYPENAME); }
- /**
- * DECLARE_CLASS_CHECKERS:
- * @ClassType: class struct name
- * @OBJ_NAME: the object name in uppercase with underscore separators
- * @TYPENAME: type name
- *
- * Direct usage of this macro should be avoided, and the complete
- * OBJECT_DECLARE_TYPE macro is recommended instead.
- *
- * This macro will provide the class type cast functions for a
- * QOM type.
- */
- #define DECLARE_CLASS_CHECKERS(ClassType, OBJ_NAME, TYPENAME) \
- static inline G_GNUC_UNUSED ClassType * \
- OBJ_NAME##_GET_CLASS(const void *obj) \
- { return OBJECT_GET_CLASS(ClassType, obj, TYPENAME); } \
- \
- static inline G_GNUC_UNUSED ClassType * \
- OBJ_NAME##_CLASS(const void *klass) \
- { return OBJECT_CLASS_CHECK(ClassType, klass, TYPENAME); }
好了,现在各个宏定义基本都已经给出了(G_DEFINE_AUTOPTR_CLEANUP_FUNC暂时不展开),开始逐层展开,到底看看完全展开之后是个内容。
第1层:
- #define OBJECT_DECLARE_TYPE(InstanceType, ClassType, MODULE_OBJ_NAME) \
- typedef struct InstanceType InstanceType; \
- typedef struct ClassType ClassType; \
- \
- G_DEFINE_AUTOPTR_CLEANUP_FUNC(InstanceType, object_unref) \
- \
- DECLARE_OBJ_CHECKERS(InstanceType, ClassType, \
- MODULE_OBJ_NAME, TYPE_##MODULE_OBJ_NAME)
代入
OBJECT_DECLARE_TYPE(MachineState, MachineClass, MACHINE)
中的实际值:InstanceType <-> MachineState,ClassType <-> MachineClass,MODULE_OBJ_NAME <-> MACHINE,得到:
- typedef struct MachineState MachineState;
- typedef struct MachineClass MachineClass;
-
- G_DEFINE_AUTOPTR_CLEANUP_FUNC(MachineState, object_unref)
-
- DECLARE_OBJ_CHECKERS(MachineState, MachineClass, \
- MACHINE, TYPE_MACHINE)
第2层:
- #define DECLARE_OBJ_CHECKERS(InstanceType, ClassType, OBJ_NAME, TYPENAME) \
- DECLARE_INSTANCE_CHECKER(InstanceType, OBJ_NAME, TYPENAME) \
- \
- DECLARE_CLASS_CHECKERS(ClassType, OBJ_NAME, TYPENAME)
代入
- DECLARE_OBJ_CHECKERS(MachineState, MachineClass, \
- MACHINE, TYPE_MACHINE)
中的实际值:InstanceType <-> MachineState,ClassType <-> MachineClass,OBJ_NAME <-> MACHINE,TYPENAME <-> TYPE_MACHINE,得到:
- DECLARE_INSTANCE_CHECKER(MachineState, MACHINE, TYPE_MACHINE)
-
- DECLARE_CLASS_CHECKERS(MachineClass, MACHINE, TYPE_MACHINE)
第3层:
- #define DECLARE_INSTANCE_CHECKER(InstanceType, OBJ_NAME, TYPENAME) \
- static inline G_GNUC_UNUSED InstanceType * \
- OBJ_NAME(const void *obj) \
- { return OBJECT_CHECK(InstanceType, obj, TYPENAME); }
和
- #define DECLARE_CLASS_CHECKERS(ClassType, OBJ_NAME, TYPENAME) \
- static inline G_GNUC_UNUSED ClassType * \
- OBJ_NAME##_GET_CLASS(const void *obj) \
- { return OBJECT_GET_CLASS(ClassType, obj, TYPENAME); } \
- \
- static inline G_GNUC_UNUSED ClassType * \
- OBJ_NAME##_CLASS(const void *klass) \
- { return OBJECT_CLASS_CHECK(ClassType, klass, TYPENAME); }
分别代入
- DECLARE_INSTANCE_CHECKER(MachineState, MACHINE, TYPE_MACHINE)
-
- DECLARE_CLASS_CHECKERS(MachineClass, MACHINE, TYPE_MACHINE)
中的实际值:InstanceType <-> MachineState,OBJ_NAME <-> MACHINE,TYPENAME <-> TYPE_MACHINE;ClassType <-> MachineClass,OBJ_NAME <-> MACHINE,TYPENAME <-> TYPE_MACHINE分别得到:
- static inline G_GNUC_UNUSED MachineState *
- MACHINE(const void *obj)
- { return OBJECT_CHECK(MachineState, obj, TYPE_MACHINE); }
- static inline G_GNUC_UNUSED MachineClass *
- MACHINE_GET_CLASS(const void *obj)
- { return OBJECT_GET_CLASS(MachineClass, obj, TYPE_MACHINE); }
-
- static inline G_GNUC_UNUSED MachineClass *
- MACHINE_CLASS(const void *klass)
- { return OBJECT_CLASS_CHECK(MachineClass, klass, TYPE_MACHINE); }
与上面综合,得到:
- typedef struct MachineState MachineState;
- typedef struct MachineClass MachineClass;
-
- G_DEFINE_AUTOPTR_CLEANUP_FUNC(MachineState, object_unref)
-
- static inline G_GNUC_UNUSED MachineState *
- MACHINE(const void *obj)
- { return OBJECT_CHECK(MachineState, obj, TYPE_MACHINE); }
-
- static inline G_GNUC_UNUSED MachineClass *
- MACHINE_GET_CLASS(const void *obj)
- { return OBJECT_GET_CLASS(MachineClass, obj, TYPE_MACHINE); }
-
- static inline G_GNUC_UNUSED MachineClass *
- MACHINE_CLASS(const void *klass)
- { return OBJECT_CLASS_CHECK(MachineClass, klass, TYPE_MACHINE); }
整理成更好理解的格式:
- typedef struct MachineState MachineState;
- typedef struct MachineClass MachineClass;
-
- G_DEFINE_AUTOPTR_CLEANUP_FUNC(MachineState, object_unref)
-
- static inline G_GNUC_UNUSED MachineState *MACHINE(const void *obj)
- {
- return OBJECT_CHECK(MachineState, obj, TYPE_MACHINE);
- }
-
- static inline G_GNUC_UNUSED MachineClass *MACHINE_GET_CLASS(const void *obj)
- {
- return OBJECT_GET_CLASS(MachineClass, obj, TYPE_MACHINE);
- }
-
- static inline G_GNUC_UNUSED MachineClass *MACHINE_CLASS(const void *klass)
- {
- return OBJECT_CLASS_CHECK(MachineClass, klass, TYPE_MACHINE);
- }
这就得到了初步形式。再将TYPE_MACHINE宏的定义(在include/hw/boards.h中)代入:
#define TYPE_MACHINE "machine"
得到:
- typedef struct MachineState MachineState;
- typedef struct MachineClass MachineClass;
-
- G_DEFINE_AUTOPTR_CLEANUP_FUNC(MachineState, object_unref)
-
- static inline G_GNUC_UNUSED MachineState *MACHINE(const void *obj)
- {
- return OBJECT_CHECK(MachineState, obj, "machine");
- }
-
- static inline G_GNUC_UNUSED MachineClass *MACHINE_GET_CLASS(const void *obj)
- {
- return OBJECT_GET_CLASS(MachineClass, obj, "machine");
- }
-
- static inline G_GNUC_UNUSED MachineClass *MACHINE_CLASS(const void *klass)
- {
- return OBJECT_CLASS_CHECK(MachineClass, klass, "machine");
- }
对比一下在 VSCode 中展开的截图:
终于看到了MACHINE函数的庐山真面目!原来是这样:
- static inline G_GNUC_UNUSED MachineState *MACHINE(const void *obj)
- {
- return OBJECT_CHECK(MachineState, obj, TYPE_MACHINE);
- }
下一回将对MACHINE函数及其相关函数进行进一步解析。