OpenHarmony轻量系统服务管理|系统服务间调用之对外接口详解

前言

本文是对Samgr部分中子主题IUnknown的总体概述,相关代码文件位于distributedschedule_samgr_lite\samgr\source。对于IUnknown的分析思路是采用1篇总体概述+n篇代码标注的方式进行技术分享。在本文中提到的数据结构或函数的详细分析可以在文末的附录中找到,其中也包含了许多优秀代码的分析。

IUnknown概述

IUnknown是鸿蒙系统中非常重要的一个概念,作为服务或功能间交互的对外接口。当创建一个服务或功能时,需要为其绑定一个对外接口。其他的服务可以通过这个接口和它交互。下面给出IUnknown的基本结构,在开发新的对外接口时都必须继承这个基类,它包含三个基本的函数指针,分别是查询接口(QueryInterface)、增加引用(AddRef)、减少引用(Release)。

struct IUnknown {
    //查询IUnknown接口
    int (*QueryInterface)(IUnknown *iUnknown, int version, void **target);
    //添加引用计数
    int (*AddRef)(IUnknown *iUnknown);
    //释放对IUnknown接口的引用
    int (*Release)(IUnknown *iUnknown);
};

通过调用QueryInterface函数,可以得到指定服务或功能的对外接口,使用这个接口就可以完成与服务的交互。AddRefRelease函数用来维护指定的接口对象,当它在程序中被其他地方使用时,它的引用数会加1,当使用者减少时,引用数也会相应的减少。通过引用数的值来决定是否需要回收它占用的内存资源。

实例分析

上面介绍了IUnknown是什么,以及它有什么。这里通过一些简单的实例分析一下它的定义、初始化、注册和使用。

鸿蒙的系统服务框架给我们提供了IUnknown基本的结构,只包含接口查询操作和增加/减少引用操作。要实现复杂的交互功能,我们还需要基于自身业务的需求为IUnknown增加更多的操作。为了便于统一维护,鸿蒙规定所有的对外接口必须继承IUnknown基类。我们知道C语言没有类和继承的概念,所以通过结构体代替类,宏定义代替继承。在IUnknown中定义了INHERIT_IUNKNOWN,用于继承IUnknown基类的三个函数指针。下面展示如何开发自定义的对外接口。

typedef struct MyApi {
    INHERIT_IUNKNOWN;    //继承IUnknown基类
    BOOL (*MyCall)(IUnknown *iUnknown, const char *buff);    //新增的函数指针,实现自己的业务功能
}MyApi;

介绍了新的对外接口如何定义后,我们进一步介绍如何定义它的实例对象结构。在后续服务或功能间交互的过程中,都是通过对外接口的实例对象来完成。下面是实例对象的定义。宏定义INHERIT_IUNKNOWNENTRY的作用也类似于继承,用于给IUnknown添加版本和引用字段信息。所以实例对象MyApiIMPL本质上是对IUnknown的再一次封装,并作为接口的实例。

typedef struct MyApiIMPL {
    INHERIT_IUNKNOWNENTRY(MyApi);
} MyApiIMPL;

下面将MyApiIMPL所有的宏定义展开,我们直观的看一下它的结构,可以更好的理解。

struct MyApiIMPL{
    //INHERIT_IUNKNOWNENTRY增加的两个字段
    uint16 ver;                   
    int16 ref;                   
    //自定义MyApi中的函数指针,前三个继承自IUnknown基类
    int (*QueryInterface)(IUnknown *iUnknown, int version, void **target);
    int (*AddRef)(IUnknown *iUnknown);
    int (*Release)(IUnknown *iUnknown);
    BOOL (*MyCall)(IUnknown *iUnknown, const char *buff);
}

要想使用自定义的对外接口,还需要初始化接口实例。初始化的过程很简单,就是给所有的字段赋值,完善接口的生命周期函数。宏定义DEFAULT_IUNKNOWN_ENTRY_BEGIN的作用就是为IUnknown的基本函数和字段赋初始值,不包括自定义字段。初始化代码示例如下。

static MyApiIMPL apiIMPL = {
    DEFAULT_IUNKNOWN_ENTRY_BEGIN,
        .MyCall= FunCall,    //自定义字段
    DEFAULT_IUNKNOWN_ENTRY_END,
};

初始化完成后,将接口实例注册到指定的服务或功能中,完成对外接口的绑定。接口注册的前提是Samgr实例对象已存在且指定的服务或功能已注册到Samgr中。在Samgr实例对象中有指定的接口注册函数RegisterFeatureApi(),指定服务名和功能名后,该接口会与其绑定。

当我们完成接口的定义、初始化、注册后,我们要如何使用它呢?前面我们提到服务或功能间的交互都是通过各自的对外接口来完成的,我们可以通过**GetFeatureApi()QueryInterface()**函数来获取指定服务和功能的对外接口。然后调用接口中的函数,向服务和功能发起交互。获取指定服务和功能的对外接口和调用示例如下。

MyApi *myApi = NULL;
//通过Samgr的获取接口函数,查询指定服务和功能对应的接口
IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
if (iUnknown == NULL) {
    return NULL;
}
//查询指定版本的接口,转化为MyApi,接口引用数+1
int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&myApi);
if (result != 0 || demoApi == NULL) {
    return NULL;
}
//调用接口中的函数向服务发消息
if (myApi->MyCall == NULL) {
    return NULL;
}
myApi->MyCall((IUnknown *)myApi, "Hello World!");
//接口使用完后,减少引用数
myApi->Release((IUnknown *)myApi);

上面讲解的是一种通用的接口定义、初始化、注册和使用的过程,实际上服务和功能间的交互还需要考虑是同进程内还是跨进程。在同进程内服务和功能的交互使用继承自IUnknown的一对接口,在跨进程服务和功能的交互是通过继承INHERIT_SERVER_IPROXYINHERIT_CLIENT_IPROXY来完成的。它们的实现思想上是一致的,这里就不额外讨论了。

总结

服务或功能间通过统一的接口对象来交互,可以减少代码的复杂性,并且不会将服务的内部细节暴露出来,封装性更高。开发自定义的对外接口的过程及使用如下:   
自定义对外接口: 继承IUnknown基类,新增自定义的业务函数指针。   
获取并初始化接口实例: 封装自定义的接口,新增字段,并为函数指针等赋值。 **注册/绑定接口实例:**将自定义的接口实例绑定到指定的服务或功能上。   
调用接口实例: 获取指定服务或功能的对外接口,调用接口中的业务函数发起交互。

总是有很多小伙伴反馈说:鸿蒙开发不知道学习哪些技术?不知道需要重点掌握哪些鸿蒙应用开发知识点? 为了解决大家这些学习烦恼。在这准备了一份很实用的鸿蒙(HarmonyOS NEXT)学习路线与学习文档给大家用来跟着学习。

针对一些列因素,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、WebGL、元服务、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植等等)鸿蒙(HarmonyOS NEXT)技术知识点。

《鸿蒙 (Harmony OS)开发学习手册》(共计892页):https://gitcode.com/HarmonyOS_MN/733GH/overview

如何快速入门?

1.基本概念
2.构建第一个ArkTS应用
3.……


在这里插入图片描述

开发基础知识

1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

基于ArkTS 开发

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

鸿蒙开发面试真题(含参考答案):https://gitcode.com/HarmonyOS_MN/733GH/overview

OpenHarmony 开发环境搭建:https://gitcode.com/HarmonyOS_MN/733GH/overview


在这里插入图片描述

《OpenHarmony源码解析》

搭建开发环境
系统架构分析

  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ……

OpenHarmony 设备开发学习手册:https://gitcode.com/HarmonyOS_MN

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值