当前位置:   article > 正文

鸿蒙linux内核的L1设备服务开发详解

鸿蒙linux内核的L1设备服务开发详解

鸿蒙linux内核的L1设备服务开发详解

​ 鸿蒙基于linux内核的L1设备的系统基于面向服务架构,提供了服务开发、服务的子功能开发、对外接口的开发、以及多服务进程、进程间服务调用的开发能力。现对此基座下的服务进行剖析并以实例方式进行讲解。

一、简介

在L1设备中服务分为两类:

  • core system service

    foundation\systemabilitymgr\safwk_lite\BUILD.gn

    deps添加依赖,由foundation进程启动加载。此种方式的服务挂载在foundation进程中。

  • system and application service

​ 以应用的方式进行启动,可以在/base/startup/init/service/etc/init.cfg中添加start service方式启动,或者以可执行程序的方式进行启动。此种方式的服务是以本身的进程启动。

二、服务的开发

首先SA服务包含两部份:服务端、子功能端,服务提供了子功能的接口有默认的接口和自定义子功能接口,子功能接口又包含了进程内接口与进程间接口。后续章节会一一进行说明。

2.1 服务端实现

2.1.1 服务声明

#include <service.h>
#include <message.h>
#include <common.h>

typedef struct ExampleService {
    INHERIT_SERVICE;
    Identity identity;
} ExampleService;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • INHERIT_SERVICE在foundation\systemabilitymgr\samgr_lite\interfaces\kits\samgr\service.h中定义如下:
#define INHERIT_SERVICE                                          \
    const char *(*GetName)(Service * service);                   \
    BOOL (*Initialize)(Service * service, Identity identity);    \
    BOOL (*MessageHandle)(Service * service, Request * request); \
    TaskConfig (*GetTaskConfig)(Service * service)
  • 1
  • 2
  • 3
  • 4
  • 5

该宏定义了服务的生命周期函数的函数指针。

  • Identity在foundation\systemabilitymgr\samgr_lite\interfaces\kits\samgr\message.h中定义如下:
struct Identity {
    /** Service ID */
    int16 serviceId;
    /** Feature ID */
    int16 featureId;
    /** Message queue ID */
    MQueueId queueId;
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

该宏定义了服务ID、默认子功能ID及消息队列ID。

  • MQueueId定义在foundation\industrialbus\modules\common.h
typedef void *MQueueId;
  • 1

关于默认子功能及消息队列指针,此处按下不表,在相应部份再进行说明,此时服务结构定义只需要添加两个宏即可。

2.1.2 实现服务的生命周期函数

实现该服务对象指向的生命周期函数。

  • 服务生命周期函数,实现示例如下:
#define EXAMPLE_SERVICE "moduleservice"
// 返回服务名称
static const char *GetName(Service *service)
{
    (void)service;
    return EXAMPLE_SERVICE;
}
// 初始化服务
static BOOL Initialize(Service *service, Identity identity)
{
    ExampleService *example = (ExampleService *)service;
    // 保存服务的唯一身份标识,用来自己的IUnknown接口对服务发消息时使用。
    example->identity = identity;
    return TRUE;
}
static BOOL MessageHandle(Service *service, Request *msg)
{
    ExampleService *example = (ExampleService *)service;
    (void)example;
    switch (msg->msgId) {
        default:break;
    }
    return FALSE;
}
static TaskConfig GetTaskConfig(Service *service)
{
    (void)service;
    TaskConfig config = {LEVEL_HIGH, PRI_NORMAL,
                         0x800, MODULE_QUEUE_SIZE, SINGLE_TASK};
    return config;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

2.1.3 创建服务对象

实例化ExampleService服务对象,将对象的生命函数指针指向其实现其实现的生命周期函数。

// 创建服务对象
static ExampleService g_example = {
    .GetName = GetName,
    .Initialize = Initialize,
    .MessageHandle = MessageHandle,
    .GetTaskConfig = GetTaskConfig,
    {-1, -1, NULL}
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

identity初始化时serviceId,featureId均为-1,queueId为空,在生命周期函数Initialize中赋值系统分配的identity。

2.1.4 注册服务

向SAMGR注册服务及接口

static void Init(void)
{
    SAMGR_GetInstance()->RegisterService((Service *)&g_example);
}
  • 1
  • 2
  • 3
  • 4

定义服务的初始化入口:

SYSEX_SERVICE_INIT(Init);
  • 1

2.2 子功能端

通过以上操作后,服务驻存在系统中,服务没有对外的接口,此时需要添加子功能feature,提供服务对外的接口。

子功能按分为两类:进程内子功能、跨进程子功能

2.2.1 定义子功能

子功能按通信方式分为两类:进程内子功能、跨进程子功能。

子功能还可以分为服务默认子功能与自定义子功能。

默认子功能不需要子功能生命周期,其生命周期由服务的生命周期管理。

2.2.1.1 进程内子功能接口
#include <iunknown.h>
typedef struct {
    INHERIT_IUNKNOWN;
    BOOL (*FeatureCall)(IUnknown *iUnknown, const char *buff);
} DefaultFeatureApi;
  • 1
  • 2
  • 3
  • 4
  • 5
2.2.1.2 跨进程子功能接口
#include <iproxy_server.h>
typedef struct {
    INHERIT_SERVER_IPROXY;
    BOOL (*FeatureCall)(IUnknown *iUnknown, const char *buff);
} CrossProcessFeatureApi;
  • 1
  • 2
  • 3
  • 4
  • 5

进程内子功能与跨进程子功能的声明表现在使用两个宏INHERIT_IUNKNOWN与INHERIT_SERVER_IPROXY

  • INHERIT_IUNKNOWN定义在foundation\systemabilitymgr\samgr_lite\interfaces\kits\samgr\iunknown.h
#define INHERIT_IUNKNOWN                                                   \
    int (*QueryInterface)(IUnknown *iUnknown, int version, void **target); \
    int (*AddRef)(IUnknown *iUnknown);                                     \
    int (*Release)(IUnknown *iUnknown)
  • 1
  • 2
  • 3
  • 4
  • INHERIT_SERVER_IPROXY定义在foundation\systemabilitymgr\samgr_lite\interfaces\kits\samgr\iunknown.h
#define INHERIT_SERVER_IPROXY \
        INHERIT_IUNKNOWN; \
        int32 (*Invoke)(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
  • 1
  • 2
  • 3

跨进程feature的定义相对进程内定义,多出来的Invoke函数指针,跨进程的方法通过此方法完成进程间通信、参数序列化与反序列化。

2.2.1.3 默认子功能

默认子功能需要将声明放在服务结构中进行声明。

以2.1.1中声明的服务为例,只需要将DefaultFeatureApi或CrossProcessFeatureApi添加至服务ExampleService中。

  • 默认进程内子功能
// 默认进程内子功能
typedef struct ExampleService {
    INHERIT_SERVICE;
    INHERIT_IUNKNOWNENTRY(DefaultFeatureApi);
    Identity identity;
} ExampleService;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 默认跨进程子功能
// 自定义跨进程子功能
typedef struct ExampleService {
    INHERIT_SERVICE;
    INHERIT_IUNKNOWNENTRY(CrossProcessFeatureApi);
    Identity identity;
} ExampleService;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

INHERIT_IUNKNOWNENTRY宏添加了子功能的版本也引用计数,定义在foundation\systemabilitymgr\samgr_lite\interfaces\kits\samgr\iunknown.h

#define INHERIT_IUNKNOWNENTRY(T) \
    uint16 ver;                   \
    int16 ref;                   \
    T iUnknown
  • 1
  • 2
  • 3
  • 4
2.2.1.4 自定义子功能

首先自定义子功能结构,然后定义子功能接口ExampleFeatureApi,子功能接口也分为进程间接口与跨进程接口。

// 定义子功能结构
typedef struct ExampleFeature {
    INHERIT_FEATURE;
    INHERIT_IUNKNOWNENTRY(ExampleFeatureApi);
    Identity identity;
} ExampleFeature;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 进程间子功能接口定义
#include <iunknown.h>
typedef struct {
    INHERIT_IUNKNOWN;
    BOOL (*FeatureCall)(IUnknown *iUnknown, const char *buff);
} ExampleFeatureApi;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 跨进程子功能接口定义
#include <iproxy_server.h>
typedef struct {
    INHERIT_SERVER_IPROXY;
    BOOL (*FeatureCall)(IUnknown *iUnknown, const char *buff);
} ExampleFeatureApi;
  • 1
  • 2
  • 3
  • 4
  • 5
  • INHERIT_FEATURE定义在foundation\systemabilitymgr\samgr_lite\interfaces\kits\samgr\feature.h
#define INHERIT_FEATURE                                                     \
const char *(*GetName)(Feature *feature);                                   \
void (*OnInitialize)(Feature *feature, Service *parent, Identity identity); \
void (*OnStop)(Feature *feature, Identity identity);                        \
BOOL (*OnMessage)(Feature *feature, Request *request);                      \
BOOL (*IsDistributed)(void)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

该宏定义了子功能的生命周期函数的函数指针。

2.2.2 服务子功能实现

  • 进程间子功能接口实现
static BOOL FeatureCall(IUnknown *iUnknown, const char *buff)
{
    (void)iUnknown;
    HILOG_INFO(1,"buff:%s\n", buff);
    HILOG_INFO(1,"[LPC Test][SyncCall API] Default Success!\n");
    return TRUE;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 跨进程子功能接口实现
enum MessageId {
    MSG_PROC,
    MSG_TIME_PROC,
};
static BOOL FeatureCall(IUnknown *iUnknown, const char *body)
{
    Request request = {.msgId = MSG_PROC, .msgValue = 0};
    request.len = (uint32_t)(strlen(body) + 1);
    request.data = malloc(request.len);
    if (request.data == NULL) {
        return FALSE;
    }
    if (strcpy_s(request.data, request.len, body) != EOK) {
        free(request.data);
        return FALSE;
    }
    ExampleFeature *feature = GET_OBJECT(iUnknown, ExampleFeature, iUnknown);
    return SAMGR_SendRequest(&g_example.identity, &request, NULL);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

FeatureCall由跨进程方法Invoke调用,然后子功能通过SAMGR_SendRequest发送请求至内核。

2.2.2 实现子功能的生命周期函数

默认子功能不需要子功能生命周期,实现子功能对象指向的生命周期函数。

  • 子功能生命周期函数,实现示例如下:
#define EXAMPLE_FEATURE "modulefeature"
enum MessageId {
    MSG_PROC,
    MSG_TIME_PROC,
};
static const char *FEATURE_GetName(Feature *feature)
{
    (void)feature;
    return EXAMPLE_FEATURE;
}
static void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity)
{
    ExampleFeature *demoFeature = (ExampleFeature *)feature;
    demoFeature->identity = identity;
    printf("serviceId:%d,featureId:%d,queueId:%p\n", identity.serviceId, identity.featureId, identity.queueId);
    printf("demoFeature:%p,g_example:%p\n", demoFeature, &g_example);
    printf("serviceId:%d,featureId:%d,queueId:%p\n",
        g_example.identity.serviceId, g_example.identity.featureId, g_example.identity.queueId);
}
static void FEATURE_OnStop(Feature *feature, Identity identity)
{
    (void)feature;
    (void)identity;
    g_example.identity.queueId = NULL;
    g_example.identity.featureId = -1;
    g_example.identity.serviceId = -1;
}
static BOOL FEATURE_OnMessage(Feature *feature, Request *request)
{
    (void)feature;
    if (request->msgId == MSG_PROC) {
        printf("[LPC Test][OnMessage: S:%s, F:%s] msgId<MSG_PROC> %s \n",
               EXAMPLE_SERVICE, feature->GetName(feature),
               (char *)request->data);
        Response response = {.data = "Yes, you did!", .len = 0};
        SAMGR_SendResponse(request, &response);
        return TRUE;
    } else {
        if (request->msgId == MSG_TIME_PROC) {
            printf("[LPC Test] OnMessage: S:%s, F:%s] Time Message Get Value<%s>!",
                EXAMPLE_SERVICE, feature->GetName(feature),
                request->msgValue ? "TRUE" : "FALSE");
            // AsyncTimeCall(GET_IUNKNOWN(g_example));
            return FALSE;
        }
    }
    printf("[LPC Test][OnMessage S:%s, F:%s] Inner Error! \n",
           EXAMPLE_SERVICE, feature->GetName(feature));
    return FALSE;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

FEATURE_OnMessage处理异步处理应答的消息。

2.2.3 创建功能对象

  • 创建进程内通信子功能对象
static ExampleFeature g_example = {
    .GetName = FEATURE_GetName,
    .OnInitialize = FEATURE_OnInitialize,
    .OnStop = FEATURE_OnStop,
    .OnMessage = FEATURE_OnMessage,
    DEFAULT_IUNKNOWN_ENTRY_BEGIN,
    .FeatureCall = FeatureCall,
    DEFAULT_IUNKNOWN_ENTRY_END,
    .identity = {-1, -1, NULL},
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 创建跨进程通信子功能对象
static ExampleFeature g_example = {
    .GetName = FEATURE_GetName,
    .OnInitialize = FEATURE_OnInitialize,
    .OnStop = FEATURE_OnStop,
    .OnMessage = FEATURE_OnMessage,
    SERVER_IPROXY_IMPL_BEGIN,.
    .Invoke = Invoke,
    .FeatureCall = FeatureCall,
    IPROXY_END,
    .identity = {-1, -1, NULL},
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • DEFAULT_IUNKNOWN_ENTRY_BEGIN…DEFAULT_IUNKNOWN_ENTRY_END
// foundation\systemabilitymgr\samgr_lite\interfaces\kits\samgr\iunknown.h
#define DEFAULT_VERSION 0x20
#define DEFAULT_IUNKNOWN_IMPL                  \
    .QueryInterface = IUNKNOWN_QueryInterface, \
    .AddRef = IUNKNOWN_AddRef,                 \
    .Release = IUNKNOWN_Release

#define IUNKNOWN_ENTRY_BEGIN(version)   \
    .ver = (version),                   \
    .ref = 1,                           \
    .iUnknown = {                       \
        DEFAULT_IUNKNOWN_IMPL

#define DEFAULT_IUNKNOWN_ENTRY_BEGIN IUNKNOWN_ENTRY_BEGIN(DEFAULT_VERSION)

#define DEFAULT_IUNKNOWN_ENTRY_END IUNKNOWN_ENTRY_END
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

此宏表示实现接口查询与引用计数方法使用系统实现的IUNKNOWN_QueryInterface、IUNKNOWN_AddRef、IUNKNOWN_Release三个方法。

  • SERVER_IPROXY_IMPL_BEGIN…IPROXY_END
// foundation\systemabilitymgr\samgr_lite\interfaces\kits\registry\iproxy_server.h
#define SERVER_PROXY_VER 0x80
#define SERVER_IMPL_PROXY_VER ((uint16)SERVER_PROXY_VER | (uint16)DEFAULT_VERSION)

#define SERVER_IPROXY_IMPL_BEGIN  IUNKNOWN_ENTRY_BEGIN(SERVER_IMPL_PROXY_VER)

#define IPROXY_END IUNKNOWN_ENTRY_END
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

此宏表示实现接口查询与引用计数方法使用系统实现的IUNKNOWN_QueryInterface、IUNKNOWN_AddRef、IUNKNOWN_Release三个方法。

两个宏校验的版本号不同。

在跨进程子功能中,需要实现Invoke接口

typedef enum {
    FEATURE_CALL,
    MY_MODULE_ASYNC_CALLBACK,
} MyModuleMsgID;

static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
{
    ExampleFeatureApi *api = (ExampleFeatureApi *)iProxy;
    ExampleFeature *feature = GET_OBJECT(api, ExampleFeature, iUnknown);
    printf("xxxxxxxxxxxxxxxxxxxxxxxxxxx api:%p,g_example:%p,feature:%p\n", api, &g_example, feature);
    BOOL ret;
    size_t tempLen = 0;
    size_t len = 0;
    switch (funcId) {
        case FEATURE_CALL:
            buf = ReadString(req, &tempLen);
            printf("[feature] tempLen:%u\n", tempLen);
            printf("[feature] req: %s\n", buf);
            break;
        default:
            WriteBool(reply, FALSE);
            break;
    }
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

2.2.4 注册子功能

  • 默认子功能

默认子功能的注册在服务注册之后。

static void Init(void)
{
    SAMGR_GetInstance()->RegisterService((Service *)&g_example);
    SAMGR_GetInstance()->RegisterDefaultFeatureApi(EXAMPLE_SERVICE, GET_IUNKNOWN(g_example));
}

SYSEX_SERVICE_INIT(Init);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 自定义子功能
static void Init(void)
{
    SAMGR_GetInstance()->RegisterFeature(EXAMPLE_SERVICE, (Feature *)&g_example);
    SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example));
    printf("[Register Test][Reg S:%s, F:%s]!\n",EXAMPLE_SERVICE, EXAMPLE_FEATURE);
}

SYSEX_FEATURE_INIT(Init);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2.2.5 服务与子功能权限

修改文件base\security\permission_lite\services\ipc_auth\include\policy_preset.h

FeaturePolicy mymoduleFeature[] = {
    {
        "modulefeature",
        {
            {
                .type = RANGE,
                .uidMin = 0,
                .uidMax = __INT_MAX__,
            },
        },
    },
};
// 在g_presetPolicies[]里面增加
    {"moduleservice", mymoduleFeature, 1},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

注意,服务名“moduleservice"与子功能名"modulefeature”,长度最长15个字节。

2.2 服务调用

2.2.1 进程内调用

#include <iunknown.h>
static DefaultFeatureApi *g_defaultProxy; 
IUnknown *iUnknown1 = SAMGR_GetInstance()->GetDefaultFeatureApi(EXAMPLE_SERVICE);
if (iUnknown1 == NULL) {
    return -1;
}
int32_t ret = iUnknown1->QueryInterface(iUnknown1, DEFAULT_VERSION, (void **)&g_defaultProxy);
if (ret != 0 || g_defaultProxy == NULL) {
    return -1;
}
ret = g_defaultProxy->FeatureCall((IUnknown *)g_defaultProxy, "Hi L1 first SA");
if (ret != 0) {
    return -1;
}
ret = g_defaultProxy->Release((IUnknown *)g_defaultProxy);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

2.2.2 跨进程调用

#include <iunknown.h>

typedef struct {
    int result;
    size_t messageLen;
    uint8_t *message;
} ServiceRspMsg;
static CrossProcessFeatureApi *g_clientProxy;

IUnknown *iUnknown2 = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
if (iUnknown2 == NULL) {
    return -1;
}
int32_t ret = iUnknown2->QueryInterface(iUnknown2, CLIENT_PROXY_VER, (void **)&g_clientProxy);
if (ret != 0 || g_clientProxy == NULL) {
    return -1;
}
IpcIo request;
char data[250];
IpcIoInit(&request, data, sizeof(data), 0);
WriteString(&request, "I want to async call good result!");
ServiceRspMsg reply = { 0 };
ret = g_clientProxy->Invoke((IUnknown *)g_clientProxy, FEATURE_CALL, &request, NULL, NULL);
if (ret != EXAMPLE_SUCCESS) {
    printf("[AsyncCall] ret:%d\n\r", ret);
}
if (ret != 0) {
    return -1;
}
ret = g_clientProxy->Release((IUnknown *)g_defaultProxy);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

执行步骤:g_clientProxy->Invoke---------->异步FeatureCall方法---------->SAMGR_SendRequest---------->FEATURE_OnMessage---------->(IPCRPC)---------->服务Invoke

2.3 参数序列化

// 序列化
IpcIo request;
char data[250];
IpcIoInit(&request, data, sizeof(data), 0);
WriteString(&request, "I want to async call good result!");
// 反序列化
buf = ReadString(req, &tempLen);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2.4 跨进程回调函数调用

  • 首先调用方定义回调函数指针与回调方法实现
typedef int (*AsyncHandlerFunc)(IOwner owner, int code);

static int CurrentCallback(IOwner owner, int code, IpcIo *reply)
{
    struct CurrentNotify *notify = (struct CurrentNotify *)owner;
    int32_t ret;
    ReadUint32(reply, &ret);
    printf("CurrentCallback................ %d\n", ret);
    notify->handler(notify->data, ret);
    return 0;
}
struct CurrentNotify {
    IOwner data;
    AsyncHandlerFunc handler;
};
......
ReplyData dataReply;
dataReply.id = 55;
IOwner notify = &dataReply; //自定义结构体
struct CurrentNotify customData = {
    .data = notify, 
    .handle = AsyncHandler
};
ret = g_clientProxy->Invoke((IUnknown *)g_clientProxy, MY_MODULE_ASYNC_CALLBACK, &request, &customData, CurrentCallback);
if (ret != 0) {
    printf("[AsyncCallBack] ret:%d\n\r", ret);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 实现子功能的回调接口
static BOOL AsyncCallBack(IUnknown *iUnknown, const char *body, Handler handler)
{
    Request request = {.msgId = MSG_PROC, .msgValue = 0};
    request.len = (uint32_t)(strlen(body) + 1);
    request.data = malloc(request.len);
    if (request.data == NULL) {
        return FALSE;
    }
    if (strcpy_s(request.data, request.len, body) != EOK) {
        free(request.data);
        return FALSE;
    }
    // ExampleFeature *feature = GET_OBJECT(iUnknown, ExampleFeature, iUnknown);
    printf("[LPC Test][AsyncCallBack API] Send request! \n");
    return SAMGR_SendRequest(&g_example.identity, &request, handler);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • Invoke反序列化结果
static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
{
    ExampleFeatureApi *api = (ExampleFeatureApi *)iProxy;
    ExampleFeature *feature = GET_OBJECT(api, ExampleFeature, iUnknown);
    printf("xxxxxxxxxxxxxxxxxxxxxxxxxxx api:%p,g_example:%p,feature:%p\n", api, &g_example, feature);
    BOOL ret;
    size_t tempLen = 0;
    uint8_t *buf = NULL;
    switch (funcId) {
        case FEATURE_CALL:
            buf = ReadString(req, &tempLen);
            printf("[feature] tempLen:%u\n", tempLen);
            printf("[feature] req: %s\n", buf);
            break;
        case MY_MODULE_ASYNC_CALLBACK: { // convert to sync proxy
            buf = ReadString(req, &tempLen);
            printf("xxxxxxxxxxxxxxxxxxxxxxxxxxx buf:%s\n", buf);
            WriteUint32(reply, 1);
            break;
        default:
            WriteBool(reply, FALSE);
            break;
    }
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/251654
推荐阅读
相关标签
  

闽ICP备14008679号