#include stdio.h#include string.h#include stdlib.h// 第一步定义核心结构体模拟QOM的Object/Class/Type // 1. 类型元信息对应QEMU的TypeImpl记录类型名父类型描述继承关系typedef struct TypeInfo {const char *name; // 类型名比如Device、PL181struct TypeInfo *parent; // 父类型继承关系} TypeInfo;// 2. 类结构体对应QEMU的ObjectClass绑定类型元信息typedef struct ObjectClass {TypeInfo *type; // 该类对应的类型元信息} ObjectClass;// 3. 基类Object对应QEMU的Objecttypedef struct Object {ObjectClass *class; // 每个对象关联一个类} Object;// 4. 设备基类DeviceState对应QEMU的DeviceState继承Objecttypedef struct DeviceState {Object parent_obj; // 父类放在第一个位置核心保证指针转换对齐const char *id; // 设备特有属性ID} DeviceState;// 5. PL181设备继承DeviceStatetypedef struct PL181State {DeviceState parent_obj; // 继承DeviceStateint irq_count; // PL181特有属性中断数量} PL181State;// 第二步定义核心辅助函数模拟QEMU的类型检查 // 1. 检查type1是否是type2的祖先对应QEMU的type_is_ancestorint type_is_ancestor(TypeInfo *type1, TypeInfo *type2) {// 遍历type1的继承链看是否能找到type2while (type1) {if (type1 type2) {return 1; // 是祖先返回true}type1 type1-parent; // 往上找父类型}return 0; // 不是祖先返回false}// 2. 类级动态转换对应QEMU的object_class_dynamic_castObjectClass *object_class_dynamic_cast(ObjectClass *class, TypeInfo *target_type) {if (!class || !target_type) {return NULL;}// 核心逻辑检查当前类的类型是否继承目标类型if (type_is_ancestor(class-type, target_type)) {return class; // 转换成功}return NULL; // 转换失败}// 3. 对象级动态转换对应QEMU的object_dynamic_castvoid *object_dynamic_cast(Object *obj, TypeInfo *target_type) {if (!obj) {return NULL;}// 先检查类是否能转换类能转则对象能转核心if (object_class_dynamic_cast(obj-class, target_type)) {return obj; // 返回原对象指针因为父类在第一个位置地址对齐}return NULL;}// 4. 简化版DEVICE宏对应QEMU的DEVICE(obj)#define DEVICE(obj) \((DeviceState *)object_dynamic_cast((Object *)obj, type_device))// 第三步初始化类型和对象模拟QEMU的设备创建 // 1. 定义类型元信息构建继承链Object → Device → PL181TypeInfo type_object {.name Object, .parent NULL};TypeInfo type_device {.name Device, .parent type_object};TypeInfo type_pl181 {.name PL181, .parent type_device};// 2. 定义类每个类绑定对应的类型元信息ObjectClass class_object {.type type_object};ObjectClass class_device {.type type_device};ObjectClass class_pl181 {.type type_pl181};// 3. 创建PL181对象模拟QEMU的设备初始化PL181State pl181_dev {.parent_obj { // 初始化DeviceState父类.parent_obj { // 初始化Object父类.class class_pl181 // 关联PL181类},.id pl181_0 // 设备ID},.irq_count 2 // PL181的中断数量};// 第四步测试类型转换 int main() {// 把PL181对象指针转为通用Object*模拟QEMU的obj参数Object *obj (Object *)pl181_dev;// 1. 测试DEVICE(obj)转换PL181→DeviceDeviceState *dev DEVICE(obj);if (dev) {printf(转换成功PL181 → Device\n);printf(设备ID%s\n, dev-id); // 能正常访问Device的属性} else {printf(转换失败\n);}// 2. 测试反向转换非法Device→PL181这里仅演示PL181State *pl181 (PL181State *)object_dynamic_cast(obj, type_pl181);if (pl181) {printf(转换成功Object → PL181\n);printf(PL181中断数量%d\n, pl181-irq_count); // 能正常访问PL181的属性}return 0;}其实核心就一句话父类的结构体是子类结构体的子集并且父类的第一个成员一定是子类的第一个成员子类转父类 天然可以 大转小父类转子类 小转大 必须确认父类是否包含了子类的各个成分。 object_class_dynamic_cast换到c语言结构体来理解就没有那么C类那么玄乎无非就是强制类型转换转换之后还能访问到相应的正确的内容。c结构体在内存中位置是相近一个整体。container_of(ptr, type, member)可执行代码在内存中也是相近的代码上下文这就涉及到指令cache的命中......