接前一篇文章:QEMU源码全解析37 —— Machine(7)
本文内容参考:
《趣谈Linux操作系统》 —— 刘超,极客时间
《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函数的庐山真面目!原来是这样:文章来源:https://www.toymoban.com/news/detail-650805.html
static inline G_GNUC_UNUSED MachineState *MACHINE(const void *obj)
{
return OBJECT_CHECK(MachineState, obj, TYPE_MACHINE);
}
下一回将对MACHINE函数及其相关函数进行进一步解析。文章来源地址https://www.toymoban.com/news/detail-650805.html
到了这里,关于QEMU源码全解析38 —— Machine(8)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!