【OpenHarmony】鸿蒙开发:进程间通信的核心机制详解(三)

📌往期推文全新看点(文中附带最新·鸿蒙全栈学习笔记)

📃 鸿蒙(HarmonyOS)北向开发知识点记录~

📃 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~

📃 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?

📃 嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~

📃 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?

📃 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?

📃 记录一场鸿蒙开发岗位面试经历~

📃 持续更新中……


函数实现详解

解析响应消息中的syscap信息
/*
    函数功能:解析响应消息中的syscap信息
    函数参数:@reply:接收的响应信息
             @sysCaps:存放syscap的数组
             @sysCapNum:数组中syscap的个数
             @isEnd:标记是否读取到结尾
             @nextRequestIdx:记录未读取的syscap下标,作为下一次读取操作的起始位置
    函数描述:从接收到的响应消息中解析syscap信息,并存储在sysCaps数组中。
             更新sysCapNum值,记录sysCaps数组中syscap的个数。
             更新isEnd值,记录是否读取到末尾。
             更新nextRequestIdx值,记录未读取的syscap下标,作为下一次读取操作的起始位置
*/
static int32 ParseGetAllSysCapsReply(IpcIo *reply, char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN],
                                     int32 *sysCapNum, BOOL *isEnd, uint32 *nextRequestIdx)
{
    //从reply中读取消息
    int32 ret = IpcIoPopInt32(reply);
    if (ret != EC_SUCCESS)
    {
        //若操作失败,则标识读取已结束
        *isEnd = TRUE;
        return ret;
    }
    //操作成功,进行消息解析
    //读取一个bool大小的消息作为isEnd的值
    *isEnd = IpcIoPopBool(reply);
    //读取一个Uint32大小的消息作为nextRequestIdx的值
    *nextRequestIdx = IpcIoPopUint32(reply);
    //读取size值
    uint32 size = IpcIoPopUint32(reply);
    //防止size值超出限制
    size = ((size > MAX_SYSCAP_NUM) ? MAX_SYSCAP_NUM : size);
    //获取syscaps中已有syscap的数目
    int cnt = *sysCapNum;
    //循环读取reply,解析关于syscap的信息
    for (int i = 0; i < size; i++)
    {
        int len = 0;
        //获取len和sysCap
        char *sysCap = (char *)IpcIoPopString(reply, &len);
        if (sysCap == NULL || len == 0)
        {
            continue;
        }
        //拷贝复制
        if (strcpy_s(sysCaps[cnt], sizeof(sysCaps[cnt]), sysCap) != EC_SUCCESS)
        {
            continue;
        }
        cnt++;
    }
    //更新个数
    *sysCapNum = cnt;
    return ret;
}
查询所有的syscap信息
/*
    函数功能:向主endpoint查询所有的syscap
    函数参数:@endpoint:当前进程的通信端点
             @sysCaps:存储syscap的数组
             @sysCapNum:数组中syscap的个数
    函数返回:查询成功 返回EC_SUCCESS,查询失败 返回EC_INVALID
    函数描述:向主endpoint发起查询syscap的请求,若未查询到末尾则不断查询,直到查询到末尾才返回。
             每次循环查询都会从上一次查询的下标开始。
             查询的syscap保存在sysCaps中,并更新sysCapNum的值。
*/
int32 SAMGR_GetSystemCapabilities(const Endpoint *endpoint,
                                  char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN], int32 *sysCapNum)
{
    //参数检查
    if (sysCapNum == NULL)
    {
        return EC_INVALID;
    }
    //初始值
    *sysCapNum = 0;
    if (endpoint == NULL)
    {
        return EC_INVALID;
    }
    HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_GetSystemCapabilities begin");
    //定义请求结构
    IpcIo reply;
    void *replyBuf = NULL;
    //查询的起始索引
    int startIdx = 0;
    //标记查询操作是否达到末尾
    BOOL isEnd = TRUE;
    int ret;
    do
    {
        //向主endpoint发送查询syscap的请求消息,操作类型为OP_ALL,查询的起始下标为startIdx。响应信息由reply和replyBuf返回
        ret = SendGetAllSysCapsRequest(endpoint, startIdx, &reply, &replyBuf);
        if (ret == EC_SUCCESS)
        {//请求成功
            //从接收到的响应消息中解析syscap信息,并存储在sysCaps数组中。
            //更新sysCapNum值,记录sysCaps数组中syscap的个数。
            //更新isEnd值,记录是否读取到末尾。
            //更新nextRequestIdx值,记录未读取的syscap下标,作为下一次查询操作的起始位置
            ret = ParseGetAllSysCapsReply(&reply, sysCaps, sysCapNum, &isEnd, &startIdx);
        }
        if (replyBuf != NULL)
        {
            //释放内存
            FreeBuffer(endpoint, replyBuf);
        }
    } while (isEnd == FALSE && ret == EC_SUCCESS);//isEnd == FALSE,即还存在syscap待读
    HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_GetSystemCapabilities ret = %d", ret);
    return ret;
}
为endpoint启动监听程序
//为endpoint创建监听,即创建一个线程,用于接收消息
static void Listen(Endpoint *endpoint)
{
    if (endpoint->boss != NULL)
    {
        //已绑定线程,则返回
        return;
    }
    //指定线程属性
    ThreadAttr attr = {endpoint->name, MAX_STACK_SIZE, PRI_ABOVE_NORMAL, 0, 0};
    /*
        为endpoint创建一个线程,用于接收其他进程发送的消息
        @1:创建的线程开始运行的函数地址
        @2:运行函数需要的参数
        @3:线程属性
    */
    endpoint->boss = (ThreadId)THREAD_Create(Receive, endpoint, &attr);
}
通信代理的比较函数
//比较两个proxy
static int CompareIServerProxy(const IServerProxy *proxy1, const IServerProxy *proxy2)
{
    //比较的是指针存储的地址值
    if (proxy1 == proxy2)
    {
        return 0;
    }
    return (proxy1 > proxy2) ? 1 : -1;
}
获取router中通信代理的键值
//将指定的对象转换为可用作比较的数据
//当前函数即将router的proxy返回,作为比较对象
static IServerProxy *GetIServerProxy(const Router *router)
{
    if (router == NULL)
    {
        return NULL;
    }
    //返回类型IServerProxy的服务端代理
    return router->proxy;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值