往期知识点整理
一、前言
在上一篇中,针对common的头文件以及实现进行了分析,本文先对上一篇的内容进行补充。再对新的iunknown部分进行分析。
二、common补充分析
在vector中按元素内容查找
/*
函数功能:根据element查询元素下标
函数参数:@vector:vector对象
@element:待查询的元素
函数返回:成功 返回元素下标,失败 返回INVALID_INDEX
详细描述:
1.判断vector对象的函数指针key是否为NULL,若不为NULL,则将element转化为key值。
2.调用VECTOR_FindByKey根据键值查询
3.若函数指针key为NULL则传element,否则传入计算后的key值
*/
int16 VECTOR_Find(Vector *vector, const void *element)
{
//参数检查
if (vector == NULL || element == NULL) {
return INVALID_INDEX;
}
//将通过element查找转化为通过键值查找
return VECTOR_FindByKey(vector, (vector->key == NULL) ? element : vector->key(element));
}
获取vector的容量及元素个数
/*
函数功能:根据键值查询元素下标
函数参数:@vector: vector对象
@key: 指定键值
函数返回:成功 返回元素下标,失败 返回INVALID_INDEX
详细描述:
1.首先检查参数
2.遍历vector的data,首先判断vector的函数指针key是否为NULL
3.若不为NULL,则计算元素对应的key值,并赋值给first,否则用当前元素赋值
4.有两种方式进行匹配,第一种直接判断first与传入的key是否相等,第二种通过compare函数比较
5.若匹配成功则返回相应下标
*/
int16 VECTOR_FindByKey(Vector *vector, const void *key)
{
//参数检查
if (vector == NULL || key == NULL) {
return INVALID_INDEX;
}
int16 i;
//遍历vector的data
for (i = 0; i < vector->top; ++i) {
//跳过data[i]为NULL的
if (vector->data[i] == NULL) {
continue;
}
//vector对象的key为NULL时first为元素指针,不为空时first为元素对应的key值
void *first = (vector->key != NULL) ? vector->key(vector->data[i]) : vector->data[i];
//判断first与key的指向是否相同
if (first == key) {
//相同,则找到指定元素,返回下标
return i;
}
//first与key的指向不相同,进一步通过键值比较函数判断
if (vector->compare == NULL || first == NULL) {
//若键值比较函数为NULL,或者first指向NULL,跳出本次循环
continue;
}
//通过比较函数比较first和key指向的值
if (vector->compare(first, key) == 0) {
return i;
}
}
return INVALID_INDEX;
}
获取vector的容量及元素个数
//获取vector对象中data的大小,包括NULL
int16 VECTOR_Size(Vector *vector)
{
if (vector == NULL) {
return INVALID_INDEX;
}
//返回top值,等于vector中最后一个元素下标+1
return vector->top;
}
//获取vector对象中data实际占用空间,即元素个数,不包括NULL
int16 VECTOR_Num(Vector *vector)
{
if (vector == NULL) {
return INVALID_INDEX;
}
//vector中元素已占用的个数top与vector已释放元素的个数free的差值
return vector->top - vector->free;
}
三、iunknown头文件
接下来进入本文的正题,对iunknown的头文件进行分析。头文件位于distributedschedule_samgr_lite\interfaces\kits\samgr\iunknown.h。iunknown为系统功能的外部功能提供基类和默认实现。
- 结构体分析
//结构体的声明,包含QueryInterface函数指针、AddRef函数指针、Release函数指针
struct IUnknown {
//查询指定版本接口的子类对象
int (*QueryInterface)(IUnknown *iUnknown, int version, void **target);
//添加引用计数
int (*AddRef)(IUnknown *iUnknown);
//释放对接口的引用
int (*Release)(IUnknown *iUnknown);
};
typedef struct IUnknownEntry {
//接口版本信息
uint16 ver;
//接口的引用计数。
int16 ref;
//IUnknown接口成员
IUnknown iUnknown;
} IUnknownEntry;
- 宏定义分析
//定义用于继承IUnknown接口的宏
//当开发IUnknown类的子类时,可以使用这个宏来继承IUnknown接口结构
#define INHERIT_IUNKNOWN \
int (*QueryInterface)(IUnknown *iUnknown, int version, void **target); \
int (*AddRef)(IUnknown *iUnknown); \
int (*Release)(IUnknown *iUnknown)
//定义用于继承实现IUnknown接口的类的宏
//当开发一个实现了IUnknown接口的类的子类时,可以使用这个宏继承IUnknown实现类的结构
#define INHERIT_IUNKNOWNENTRY(T) \
uint16 ver; \
int16 ref; \
T iUnknown
//定义初始化IUnknown接口的默认宏
//当创建IUnknown接口的子类对象时,可以使用此宏将IUnknown接口的成员初始化为默认值
#define DEFAULT_IUNKNOWN_IMPL \
.QueryInterface = IUNKNOWN_QueryInterface, \
.AddRef = IUNKNOWN_AddRef, \
.Release = IUNKNOWN_Release
//定义用于初始化实现IUnknown接口的类的宏。
//当创建实现IUnknown接口的类的子类对象时,可以使用这个宏将IUnknown实现类的成员初始化为默认值
#define IUNKNOWN_ENTRY_BEGIN(version) \
.ver = (version), \
.ref = 1, \
.iUnknown = { \
DEFAULT_IUNKNOWN_IMPL
四、结语
本篇文章首先对common剩余部分的内容进行了分析,然后对iunknown头文件中的一些内容进行介绍。要想深入的理解iunknown是什么以及有什么作用,可以继续阅读下一篇文章,关于iunknown的实现分析。
最后
总是有很多小伙伴反馈说:鸿蒙开发不知道学习哪些技术?不知道需要重点掌握哪些鸿蒙开发知识点? 为了解决大家这些学习烦恼。在这准备了一份很实用的鸿蒙全栈开发学习路线与学习文档给大家用来跟着学习。
针对一些列因素,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植……等)技术知识点。
《鸿蒙 (Harmony OS)开发学习手册》(共计892页):https://gitcode.com/HarmonyOS_MN/733GH/overview
如何快速入门?
1.基本概念
2.构建第一个ArkTS应用
3.……
鸿蒙开发面试真题(含参考答案):
《OpenHarmony源码解析》:
- 搭建开发环境
- Windows 开发环境的搭建
- Ubuntu 开发环境搭建
- Linux 与 Windows 之间的文件共享
- ……
- 系统架构分析
- 构建子系统
- 启动流程
- 子系统
- 分布式任务调度子系统
- 分布式通信子系统
- 驱动子系统
- ……