QEMU源码全解析27 —— QOM介绍(16)

接前一篇文章:QEMU源码全解析26 —— QOM介绍(15)

本文内容参考:

《趣谈Linux操作系统》 —— 刘超,极客时间

《QEMU/KVM》源码解析与应用 —— 李强,机械工业出版社

特此致谢!

前文讲解了对象属性的设置接口。本文讲解对象属性的获取接口。实际上机制是很相似的。

对象属性的设置是通过object_property_get函数来完成的。该函数同样在qom/object.c中,代码如下:

bool object_property_get(Object *obj, const char *name, Visitor *v,Error **errp)
{Error *err = NULL;ObjectProperty *prop = object_property_find_err(obj, name, errp);if (prop == NULL) {return false;}if (!prop->get) {error_setg(errp, QERR_PERMISSION_DENIED);return false;}prop->get(obj, v, name, prop->opaque, &err);error_propagate(errp, err);return !err;
}

其实object_property_get函数只是简单地调用了ObjectProperty的get函数。

每一种属性类型都有自己的get函数,如布尔(bool)、字符串(str)、enum(枚举)等。它们都在qom/object.c中,逐个来看:

static void property_get_str(Object *obj, Visitor *v, const char *name,void *opaque, Error **errp)
{StringProperty *prop = opaque;char *value;Error *err = NULL;value = prop->get(obj, &err);if (err) {error_propagate(errp, err);return;}visit_type_str(v, name, &value, errp);g_free(value);
}
static void property_get_enum(Object *obj, Visitor *v, const char *name,void *opaque, Error **errp)
{EnumProperty *prop = opaque;int value;Error *err = NULL;value = prop->get(obj, &err);if (err) {error_propagate(errp, err);return;}visit_type_enum(v, name, &value, prop->lookup, errp);
}
static void property_get_bool(Object *obj, Visitor *v, const char *name,void *opaque, Error **errp)
{BoolProperty *prop = opaque;bool value;Error *err = NULL;value = prop->get(obj, &err);if (err) {error_propagate(errp, err);return;}visit_type_bool(v, name, &value, errp);
}

仍以bool为例进行讲解。可以看到,property_get_bool函数调用了具体属性(BoolProperty)的get函数,这是在创建这个属性的时候指定的。上一回已经讲过,对象属性的添加是通过object_property_add接口完成的。而bool类型对象属性的添加object_property_add_bool函数则是调用了此接口。object_property_add_bool函数在qom/object.c中,代码如下:

ObjectProperty *
object_property_add_bool(Object *obj, const char *name,bool (*get)(Object *, Error **),void (*set)(Object *, bool, Error **))
{BoolProperty *prop = g_malloc0(sizeof(*prop));prop->get = get;prop->set = set;return object_property_add(obj, name, "bool",get ? property_get_bool : NULL,set ? property_set_bool : NULL,property_release_data,prop);
}

从这个函数中就可以看到,BoolProperty结构的set成员函数为调用object_property_add_bool函数时传入的参数,形参为:void (*get)(Object *, Error **)。在object_property_add_bool函数中调用了上边的property_get_bool函数,在property_set_bool函数中最终调用了形参void (*get)(Object *, Error **)对应的实参,即真正对象属性的获取函数。

仍以machine为例,hw/core/machine.c的machine_initfn函数代码如下:

static void machine_initfn(Object *obj)
{MachineState *ms = MACHINE(obj);MachineClass *mc = MACHINE_GET_CLASS(obj);container_get(obj, "/peripheral");container_get(obj, "/peripheral-anon");ms->dump_guest_core = true;ms->mem_merge = true;ms->enable_graphics = true;ms->kernel_cmdline = g_strdup("");ms->ram_size = mc->default_ram_size;ms->maxram_size = mc->default_ram_size;if (mc->nvdimm_supported) {Object *obj = OBJECT(ms);ms->nvdimms_state = g_new0(NVDIMMState, 1);object_property_add_bool(obj, "nvdimm",machine_get_nvdimm, machine_set_nvdimm);object_property_set_description(obj, "nvdimm","Set on/off to enable/disable ""NVDIMM instantiation");object_property_add_str(obj, "nvdimm-persistence",machine_get_nvdimm_persistence,machine_set_nvdimm_persistence);object_property_set_description(obj, "nvdimm-persistence","Set NVDIMM persistence""Valid values are cpu, mem-ctrl");}if (mc->cpu_index_to_instance_props && mc->get_default_cpu_node_id) {ms->numa_state = g_new0(NumaState, 1);object_property_add_bool(obj, "hmat",machine_get_hmat, machine_set_hmat);object_property_set_description(obj, "hmat","Set on/off to enable/disable ""ACPI Heterogeneous Memory Attribute ""Table (HMAT)");}/* default to mc->default_cpus */ms->smp.cpus = mc->default_cpus;ms->smp.max_cpus = mc->default_cpus;ms->smp.sockets = 1;ms->smp.dies = 1;ms->smp.clusters = 1;ms->smp.cores = 1;ms->smp.threads = 1;machine_copy_boot_config(ms, &(BootConfiguration){ 0 });
}

关注此函数中的以下代码:

object_property_add_bool(obj, "hmat",machine_get_hmat, machine_set_hmat);

代码中的machine_get_machine函数就是传入object_property_add_bool函数的与形参bool (*get)(Object *, Error **)对应的实参,也即对于machine对象属性进行获取时实际调用的函数。

至此,

对象的属性的添加、设置和获取就讲解完了。下一回开始讲解类的属性的添加、设置和获取。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/25912.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

项目管理和产品管理之间的区别

产品管理和项目管理是两个在企业中至关重要的职能部门,它们各自承担着不同的职责和任务。虽然两者在某些方面存在重叠,但它们的核心目标和方法有很大的不同。本文将对产品管理和项目管理进行详细的比较和分析。 “项目管理和产品管理有什么区别&#xff…

[国产MCU]-BL602-开发实例-DMA数据传输

DMA数据传输 文章目录 DMA数据传输1、DMA介绍2、DMA驱动API介绍3、DMA使用示例DMA(Direct Memory Access)是一种内存存取技术,可以独立地直接读写系统内存,而不需处理器介入处理。 在同等程度的处理器负担下,DMA是一种快速的数据传送方式。 BL602的DMA控制器有4组独立专用通…

赴日IT培训 赴日程序员工作适合什么人?

日本作为全球第三大经济体,IT行业发展十分迅速,日本拥有世界领先的科技公司,如索尼、丰田、日立等,这为IT行业提供了广阔的发展平台和良好的职业前景。此外,日本政府对IT行业也给予了充分的政策支持,像是对…

了解 spring MVC + 使用spring MVC - springboot

前言 本篇介绍什么是spring MVC ,如何使用spring MVC,了解如何连接客户端与后端,如何从前端获取各种参数;如有错误,请在评论区指正,让我们一起交流,共同进步! 文章目录 前言1. 什么…

概念解析 | 利用MIMO雷达技术实现高性能目标检测的关键技术解析

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:MIMO雷达目标检测技术 参考资料:何子述, 程子扬, 李军, 等. 集中式 MIMO 雷达研究综述[J]. 雷达学报, 2022, 11(5): 805-829. 利用MIMO雷达技术实现高性能目标检测的关键技术解…

av_buffer_ref in libwebrtc.a is referenced by DSO, final link failed:bad value

这不是在编译阶段,是在链接库时出的问题。 此时执行 ldconfig会发现很多库提示如下: is not a symbolic link也就是这些库被认为是连接库,但是它没有连接到其他库上。应该把他连接到实体的库上。如果它本身就是一个实体的库,那么…

C语言单链表OJ题(较难)

一、链表分割 牛客网链接 题目描述: 现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。 思路:…

java+springboot+mysql员工工资管理系统

项目介绍: 使用javaspringbootmysql开发的员工工资管理系统,系统包含超级管理员,系统管理员、员工角色,功能如下: 超级管理员:管理员管理;部门管理;员工管理;奖惩管理&…

【BASH】回顾与知识点梳理(六)

【BASH】回顾与知识点梳理 六 六. 管线命令 (pipe)6.1 撷取命令: cut, grepcutgrep 6.2 排序命令: sort, wc, uniqsortuniqwc 6.3 双向重导向: tee6.4 字符转换命令: tr, col, join, paste, expandtrcoljoinpasteexpand 6.5 分区命…

element-ui - $prompt非空验证

//点击删除按钮 delStoreFun(data) { let than this; this.$prompt(删除门店请填写备注, 提示, { confirmButtonText: 确定, cancelButtonText: 取消, inputValidator: (value) > { //非空验证 if (!value) { return 输入不能为空 } }, }).then(({ value }) > { delS…

C语言预备知识

安装Visual studio 官方网址 https://visualstudio.microsoft.com/zh-hans/ 选择第一个社区版本(免费) 下载完成后打开安装包 安装完成后会自动打开程序选择c项目然后安装即可(c兼容c) 安装完成后启动程序注意这里需要注册也可…

java.util.NoSuchElementException: No value present-报错(已解决)

阿丹: 今天在spring-boot整合MongoDB的过程中出现了下面的错误,是因为追求新技术、更优雅产生的。 记录一下。 错误截图如下: 错误位置代码如下: 主要问题(问题原因): 因为之前升级了我的jdk的…

css实现文字颜色渐变+阴影

效果 代码 <div class"top"><div class"top-text" text"总经理驾驶舱">总经理驾驶舱</div> </div><style lang"scss" scoped>.top{width: 100%;text-align: center;height: 80px;line-height: 80px;fo…

前端架构师的具体职责范围(合集)

前端架构师的具体职责范围1 职责&#xff1a; 1、前端技术选型、架构搭建、制定前端开发规范&#xff0c;并编制相关文档 2、负责搭建前端框架、通用组件方案制定、性能优化相关工作; 3、维护和升级本地开发环境&#xff0c;提高开发效率&#xff0c;提升开发质量; 4、推动…

JavaScript对象的方法与原型链

在JavaScript中&#xff0c;对象是一种非常重要的数据类型&#xff0c;它允许我们将多个属性和方法组织在一起。对象的方法和原型链是理解JavaScript中面向对象编程的关键概念。本文将详细讲解对象的方法和原型链&#xff0c;用通俗易懂的方式帮助你深入理解这些概念。 1. 对象…

postgresql 使用之 存储架构 触摸真实数据的存储结构以及组织形式,存入数据库的数据原来在这里

存储架构 ​专栏内容&#xff1a; postgresql内核源码分析 手写数据库toadb 并发编程 个人主页&#xff1a;我的主页 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物. 概述 postgresql 数据库服务运行时&#xff0c;数据在磁…

【Linux】IO 篇:文件调用原理,文件描述符,FILE的内涵,解析重定向,理解缓冲区,软硬链接

文章目录 一、系统调用接口二、文件调用1. 文件描述符 fd2. 文件调用原理3. FILE 三、重定向dup2 四、缓冲区简易 FILE 的代码实现 五、ext2 文件系统1. inode 和 文件名2. 重新认识目录3. 理解文件的增删查改4. 一些补充 六、文件链接1. 建立软连接2. 建立硬连接 文件被加载之…

前后端开发的区别是什么?

VUE的开发方式为什么和后端的MVC开发方式不一样呢&#xff1f; 实际上&#xff0c;Vue 和后端开发的 MVC&#xff08;Model-View-Controller&#xff09;方式是不同的&#xff0c;因为它们面对的问题和场景也不同。 前端与后端的职责不同&#xff1a; 前端和后端的职责和任务不…

ARM 内存屏障指令

ARM 内存屏障指令 1. dmb (Data Memory Barrier) 数据内存栅栏2. dsb (Data Synchronization Barrier) 数据同步栅栏3. isb (Instruction Synchronization Barrier) 指令同步栅栏4. ARM 内存屏障指令如何选择使用&#xff1f;5. 使用示例5.1. DMB指令示例&#xff1a;5.2. DSB指…

java.lang.IllegalStateException: Failed to load ApplicationContext

问题描述 原因是我在进行微服务远程调用的时候报的错误。 解决方案 原来是jdk版本不一样导致的问题&#xff0c;改成1.8就行了