1# 轻量型系统服务管理部件<a name="ZH-CN_TOPIC_0000001081604584"></a> 2 3- [简介](#section11660541593) 4- [目录](#section1464106163817) 5- [约束](#section1718733212019) 6- [开发服务](#section159991817144514) 7- [开发服务的子功能](#section11510542164514) 8- [开发进程内对外接口](#section1685211117463) 9- [调用进程内服务](#section3690162916462) 10- [开发跨进程间对外接口](#section9220246194615) 11- [调用跨进程间服务](#section114372711475) 12- [开发跨进程间服务调用客户端代理](#section09341923114710) 13- [相关仓](#section10365113863719) 14 15## 简介<a name="section11660541593"></a> 16 17由于平台资源有限,且硬件平台多样,因此需要屏蔽不同硬件架构和平台资源的不同、以及运行形态的不同,提供统一化的系统服务开发框架。根据RISC-V、Cortex-M、Cortex-A不同硬件平台,分为两种硬件平台,以下简称M核、A核。 18 19- M核:处理器架构为Cortex-M或同等处理能力的硬件平台,系统内存一般低于512KB,无文件系统或者仅提供一个可有限使用的轻量级文件系统,遵循CMSIS接口规范。 20- A核:处理器架构为Cortex-A或同等处理能力的硬件平台,内存资源大于512KB,文件系统完善,可存储大量数据,遵循POSIX接口规范。 21 22系统服务框架基于面向服务的架构,提供了服务开发、服务的子功能开发、对外接口的开发、以及多服务共进程、进程间服务调用等开发能力。其中: 23 24- M核:包含服务开发、服务的子功能开发、对外接口的开发以及多服务共进程的开发框架。 25- A核:在M核能力基础之上,包含了进程间服务调用、进程间服务调用权限控制、进程间服务接口的开发等能力。 26 27## 系统架构<a name="section342962219551"></a> 28 29**图 1** 面向服务的架构 30 31 32![](figures/zh-cn_image_0000001128146921.png) 33 34- Provider:服务的提供者,为系统提供能力(对外接口)。 35- Consumer:服务的消费者,调用服务提供的功能(对外接口)。 36- Samgr:作为中介者,管理Provider提供的能力,同时帮助Consumer发现Provider的能力。 37 38**图 2** 系统服务开发框架主体对象: 39 40![](figures/zh-cn_image_0000001081285004.png) 41 42- SamgrLite:主要提供服务的注册与发现能力。 43- Service:开发服务时,需要实现的服务的生命周期接口。 44- Feature:开发功能时,需要实现的功能的生命周期接口。 45- IUnknown:基于IUnknown开发服务或功能的对外接口。 46- IClientProxy:IPC调用时,消费者的消息发送代理。 47- IServerProxy:IPC调用时,开发者需要实现提供者的消息处理接口。 48 49## 目录<a name="section1464106163817"></a> 50 51**表 1** 系统服务框架源代码目录结构 52 53<a name="table2977131081412"></a> 54<table><thead align="left"><tr id="row7977610131417"><th class="cellrowborder" valign="top" width="31.3%" id="mcps1.2.3.1.1"><p id="p18792459121314"><a name="p18792459121314"></a><a name="p18792459121314"></a>名称</p> 55</th> 56<th class="cellrowborder" valign="top" width="68.7%" id="mcps1.2.3.1.2"><p id="p77921459191317"><a name="p77921459191317"></a><a name="p77921459191317"></a>描述</p> 57</th> 58</tr> 59</thead> 60<tbody><tr id="row17977171010144"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p2793159171311"><a name="p2793159171311"></a><a name="p2793159171311"></a>interfaces/kits/samgr_lite/samgr</p> 61</td> 62<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p879375920132"><a name="p879375920132"></a><a name="p879375920132"></a>M核和A核系统服务框架对外接口定义。</p> 63</td> 64</tr> 65<tr id="row6978161091412"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p37931659101311"><a name="p37931659101311"></a><a name="p37931659101311"></a>interfaces/kits/samgr_lite/registry</p> 66</td> 67<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p6793059171318"><a name="p6793059171318"></a><a name="p6793059171318"></a>A核进程间服务调用的对外接口定义。</p> 68</td> 69</tr> 70<tr id="row6978201031415"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p117935599130"><a name="p117935599130"></a><a name="p117935599130"></a>interfaces/kits/samgr_lite/communication/broadcast</p> 71</td> 72<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p0793185971316"><a name="p0793185971316"></a><a name="p0793185971316"></a>M核和A核进程内事件广播服务的对外接口定义。</p> 73</td> 74</tr> 75<tr id="row124243183397"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p104249183396"><a name="p104249183396"></a><a name="p104249183396"></a>services/samgr_lite/samgr/adapter</p> 76</td> 77<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p2424318203914"><a name="p2424318203914"></a><a name="p2424318203914"></a>POSIX和CMSIS接口适配层来屏蔽A核M核接口差异。</p> 78</td> 79</tr> 80<tr id="row1634915717405"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p193493571406"><a name="p193493571406"></a><a name="p193493571406"></a>services/samgr_lite/samgr/registry</p> 81</td> 82<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p14349257184012"><a name="p14349257184012"></a><a name="p14349257184012"></a>M核服务注册发现的桩函数。</p> 83</td> 84</tr> 85<tr id="row1385432741312"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p1485582714135"><a name="p1485582714135"></a><a name="p1485582714135"></a>services/samgr_lite/samgr/source</p> 86</td> 87<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p085522751319"><a name="p085522751319"></a><a name="p085522751319"></a>M核和A核系统服务开发框架基础代码。</p> 88</td> 89</tr> 90<tr id="row7968155877"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p89681851717"><a name="p89681851717"></a><a name="p89681851717"></a>services/samgr_lite/samgr_client</p> 91</td> 92<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p169681051873"><a name="p169681051873"></a><a name="p169681051873"></a>A核进程间服务调用的注册与发现。</p> 93</td> 94</tr> 95<tr id="row18291912179"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p1729111214715"><a name="p1729111214715"></a><a name="p1729111214715"></a>services/samgr_lite/samgr_server</p> 96</td> 97<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p7839893352"><a name="p7839893352"></a><a name="p7839893352"></a>A核进程间服务调用的IPC地址管理和访问控制。</p> 98</td> 99</tr> 100<tr id="row6971514279"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p1797118141671"><a name="p1797118141671"></a><a name="p1797118141671"></a>services/samgr_lite/samgr_endpoint</p> 101</td> 102<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p597119145716"><a name="p597119145716"></a><a name="p597119145716"></a>A核IPC通信消息收发包管理。</p> 103</td> 104</tr> 105<tr id="row33121991272"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p143121991875"><a name="p143121991875"></a><a name="p143121991875"></a>services/samgr_lite/communication/broadcast</p> 106</td> 107<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p16312169179"><a name="p16312169179"></a><a name="p16312169179"></a>M核和A核进程内事件广播服务。</p> 108</td> 109</tr> 110</tbody> 111</table> 112 113## 约束<a name="section1718733212019"></a> 114 115- 系统服务开发框架统一使用C开发。 116- 同进程内服务间调用统一使用IUnknown接口对外象,消息接口统一由IUnknown接口传递给本服务。 117- 服务名和功能名必需使用常量字符串且长度小于16个字节。 118- M核:系统依赖上bootstrap服务,在系统启动函数中调用OHOS\_SystemInit\(\)函数。 119- A核:系统依赖samgr库,在main函数中调用SAMGR\_Bootstrap\(\)函数。 120 121## 开发服务<a name="section159991817144514"></a> 122 123- 继承并重新定义服务: 124 125 ``` 126 typedef struct ExampleService { 127 INHERIT_SERVICE; 128 INHERIT_IUNKNOWNENTRY(DefaultFeatureApi); 129 Identity identity; 130 } ExampleService; 131 ``` 132 133- 实现服务的生命周期函数: 134 135 ``` 136 static const char *GetName(Service *service) 137 { 138 return EXAMPLE_SERVICE; 139 } 140 141 static BOOL Initialize(Service *service, Identity identity) 142 { 143 ExampleService *example = (ExampleService *)service; 144 // 保存服务的唯一身份标识,用来自己的IUnknown接口对服务发消息时使用。 145 example->identity = identity; 146 return TRUE; 147 } 148 static BOOL MessageHandle(Service *service, Request *msg) 149 { 150 ExampleService *example = (ExampleService *)service; 151 switch (msg->msgId) { 152 case MSG_SYNC: 153 // 业务处理 154 break; 155 default:break; 156 } 157 return FALSE; 158 } 159 static TaskConfig GetTaskConfig(Service *service) 160 { 161 TaskConfig config = {LEVEL_HIGH, PRI_BELOW_NORMAL, 162 0x800, 20, SHARED_TASK}; 163 return config; 164 } 165 ``` 166 167- 创建服务对象: 168 169 ``` 170 static ExampleService g_example = { 171 .GetName = GetName, 172 .Initialize = Initialize, 173 .MessageHandle = MessageHandle, 174 .GetTaskConfig = GetTaskConfig, 175 SERVER_IPROXY_IMPL_BEGIN, 176 .Invoke = NULL, 177 .SyncCall = SyncCall, 178 IPROXY_END, 179 }; 180 ``` 181 182- 向SAMGR注册服务及接口: 183 184 ``` 185 static void Init(void) 186 { 187 SAMGR_GetInstance()->RegisterService((Service *)&g_example); 188 SAMGR_GetInstance()->RegisterDefaultFeatureApi(EXAMPLE_SERVICE, GET_IUNKNOWN(g_example)); 189 } 190 ``` 191 192- 定义服务的初始化入口: 193 194 ``` 195 SYSEX_SERVICE_INIT(Init); 196 197 ``` 198 199 200## 开发服务的子功能<a name="section11510542164514"></a> 201 202- 继承并重新定义功能: 203 204 ``` 205 typedef struct DemoFeature { 206 INHERIT_FEATURE; 207 INHERIT_IUNKNOWNENTRY(DemoApi); 208 Identity identity; 209 Service *parent; 210 } DemoFeature; 211 ``` 212 213- 实现功能的生命周期函数: 214 215 ``` 216 static const char *FEATURE_GetName(Feature *feature) 217 { 218 return EXAMPLE_FEATURE; 219 } 220 221 static void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity) 222 { 223 DemoFeature *demoFeature = (DemoFeature *)feature; 224 demoFeature->identity = identity; 225 demoFeature->parent = parent; 226 } 227 228 static void FEATURE_OnStop(Feature *feature, Identity identity) 229 { 230 g_example.identity.queueId = NULL; 231 g_example.identity.featureId = -1; 232 g_example.identity.serviceId = -1; 233 } 234 235 static BOOL FEATURE_OnMessage(Feature *feature, Request *request) 236 { 237 if (request->msgId == MSG_PROC) { 238 Response response = {.data = "Yes, you did!", .len = 0}; 239 SAMGR_SendResponse(request, &response); 240 return TRUE; 241 } else { 242 if (request->msgId == MSG_TIME_PROC) { 243 LOS_Msleep(WAIT_FEATURE_PROC * 10); 244 if (request->msgValue) { 245 SAMGR_PrintServices(); 246 } else { 247 SAMGR_PrintOperations(); 248 } 249 AsyncTimeCall(GET_IUNKNOWN(g_example)); 250 return FALSE; 251 } 252 } 253 return FALSE; 254 } 255 ``` 256 257- 创建功能对象: 258 259 ``` 260 static DemoFeature g_example = { 261 .GetName = FEATURE_GetName, 262 .OnInitialize = FEATURE_OnInitialize, 263 .OnStop = FEATURE_OnStop, 264 .OnMessage = FEATURE_OnMessage, 265 DEFAULT_IUNKNOWN_ENTRY_BEGIN, 266 .AsyncCall = AsyncCall, 267 .AsyncTimeCall = AsyncTimeCall, 268 .SyncCall = SyncCall, 269 .AsyncCallBack = AsyncCallBack, 270 DEFAULT_IUNKNOWN_ENTRY_END, 271 .identity = {-1, -1, NULL}, 272 }; 273 ``` 274 275- 向SAMGR注册功能及接口: 276 277 ``` 278 static void Init(void){ 279 SAMGR_GetInstance()->RegisterFeature(EXAMPLE_SERVICE, (Feature *)&g_example); 280 SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example)); 281 } 282 ``` 283 284- 定义功能的初始化入口: 285 286 ``` 287 SYSEX_FEATURE_INIT(Init); 288 289 ``` 290 291 292## 开发进程内对外接口<a name="section1685211117463"></a> 293 294- 定义IUnknown接口: 295 296 ``` 297 typedef struct DemoApi { 298 INHERIT_IUNKNOWN; 299 BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff); 300 BOOL (*AsyncTimeCall)(IUnknown *iUnknown); 301 BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload); 302 BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, Handler handler); 303 } DemoApi; 304 ``` 305 306- 定义IUnknown的引用对象: 307 308 ``` 309 typedef struct DemoRefApi { 310 INHERIT_IUNKNOWNENTRY(DemoApi); 311 } DemoRefApi; 312 ``` 313 314- 初始化接口对象: 315 316 ``` 317 static DemoRefApi api = { 318 DEFAULT_IUNKNOWN_ENTRY_BEGIN, 319 .AsyncCall = AsyncCall, 320 .AsyncTimeCall = AsyncTimeCall, 321 .SyncCall = SyncCall, 322 .AsyncCallBack = AsyncCallBack, 323 DEFAULT_IUNKNOWN_ENTRY_END, 324 }; 325 ``` 326 327- 注册服务接口: 328 329 ``` 330 SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(api)); 331 332 ``` 333 334 335## 调用进程内服务<a name="section3690162916462"></a> 336 337- 获取服务的对外接口: 338 339 ``` 340 DemoApi *demoApi = NULL; 341 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE); 342 if (iUnknown == NULL) { 343 return NULL; 344 } 345 int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi); 346 if (result != 0 || demoApi == NULL) { 347 return NULL; 348 } 349 ``` 350 351- 接口调用: 352 353 ``` 354 if (demoApi->AsyncCallBack == NULL) { 355 return NULL; 356 } 357 demoApi->AsyncCallBack((IUnknown *)demoApi, "I wanna async call callback good result!", AsyncHandler); 358 ``` 359 360- 释放接口: 361 362 ``` 363 int32 ref = demoApi->Release((IUnknown *)demoApi); 364 365 ``` 366 367 368## 开发跨进程间对外接口<a name="section9220246194615"></a> 369 370- 继承IServerProxy替代继承IUnknown:INHERIT\_SERVER\_IPROXY 371 372 ``` 373 typedef struct DemoFeatureApi { 374 INHERIT_SERVER_IPROXY; 375 BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff); 376 BOOL (*AsyncTimeCall)(IUnknown *iUnknown); 377 BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload); 378 BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler); 379 } DemoFeatureApi; 380 ``` 381 382- 初始化IServerProxy对象: 383 384 ``` 385 static DemoFeature g_example = { 386 SERVER_IPROXY_IMPL_BEGIN, 387 .Invoke = Invoke, 388 .AsyncCall = AsyncCall, 389 .AsyncTimeCall = AsyncTimeCall, 390 .SyncCall = SyncCall, 391 .AsyncCallBack = AsyncCallBack, 392 IPROXY_END, 393 }; 394 ``` 395 396- 实现Invoke函数来处理Ipc消息: 397 398 ``` 399 static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply) 400 { 401 DemoFeatureApi *api = (DemoFeatureApi *)iProxy; 402 BOOL ret; 403 size_t len = 0; 404 switch (funcId) { 405 case ID_ASYNCALL: 406 ret = api->AsyncCall((IUnknown *)iProxy, (char *)IpcIoPopString(req, &len)); 407 IpcIoPushBool(reply, ret); 408 break; 409 case ID_ASYNTIMECALL: 410 ret = api->AsyncTimeCall((IUnknown *)iProxy); 411 IpcIoPushBool(reply, ret); 412 break; 413 case ID_SYNCCALL: { 414 struct Payload payload; 415 payload.id = IpcIoPopInt32(req); 416 payload.value = IpcIoPopInt32(req); 417 payload.name = (char *)IpcIoPopString(req, &len); 418 ret = api->SyncCall((IUnknown *)iProxy, &payload); 419 IpcIoPushString(reply, ret ? "TRUE" : "FALSE"); 420 } 421 break; 422 case ID_ASYNCCALLBACK: { // convert to sync proxy 423 IpcIoPushString(reply, "Yes, you did!"); 424 IpcIoPushBool(reply, TRUE); 425 } 426 break; 427 default: 428 IpcIoPushBool(reply, FALSE); 429 break; 430 } 431 return EC_SUCCESS; 432 } 433 ``` 434 435- 注册接口:与进程内接口注册一致 436 437 ``` 438 SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example)); 439 440 ``` 441 442 443## 调用跨进程间服务<a name="section114372711475"></a> 444 445- 获取跨进程服务的对外接口: 446 447 ``` 448 IClientProxy *demoApi = NULL; 449 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE); 450 if (iUnknown == NULL) { 451 return NULL; 452 } 453 int result = iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&demoApi); 454 if (result != 0 || demoApi == NULL) { 455 return NULL; 456 } 457 ``` 458 459- 调用Ipc消息接口: 460 461 ``` 462 IpcIo request;char data[250]; 463 IpcIoInit(&request, data, sizeof(data), 0); 464 demoApi->Invoke(demoApi, 0, &request, NULL, NULL); 465 ``` 466 467- 释放接口: 468 469 ``` 470 int32 ref = demoApi->Release((IUnknown *)demoApi); 471 472 ``` 473 474 475## 开发跨进程间服务调用客户端代理<a name="section09341923114710"></a> 476 477- 定义IPC接口客户端代理: 478 479 ``` 480 typedef struct DemoClientProxy { 481 INHERIT_CLIENT_IPROXY; 482 BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff); 483 BOOL (*AsyncTimeCall)(IUnknown *iUnknown); 484 BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload); 485 BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler); 486 } DemoClientProxy; 487 typedef struct DemoClientEntry { 488 INHERIT_IUNKNOWNENTRY(DemoClientProxy); 489 } DemoClientEntry; 490 ``` 491 492- 实现客户端代理封装Ipc消息接口: 493 494 ``` 495 static BOOL AsyncCall(IUnknown *iUnknown, const char *buff) 496 { 497 DemoClientProxy *proxy = (DemoClientProxy *)iUnknown; 498 IpcIo request; 499 char data[MAX_DATA_LEN]; 500 IpcIoInit(&request, data, MAX_DATA_LEN, 0); 501 IpcIoPushString(&request, buff); 502 int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCALL, &request, NULL, NULL); 503 return ret == EC_SUCCESS; 504 } 505 506 static BOOL AsyncTimeCall(IUnknown *iUnknown) 507 { 508 DemoClientProxy *proxy = (DemoClientProxy *)iUnknown; 509 IpcIo request; 510 char data[MAX_DATA_LEN]; 511 IpcIoInit(&request, data, MAX_DATA_LEN, 0); 512 int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNTIMECALL, &request, NULL, NULL); 513 return ret == EC_SUCCESS; 514 } 515 516 static int Callback(IOwner owner, int code, IpcIo *reply) 517 { 518 size_t len = 0; 519 return strcpy_s(owner, MAX_DATA_LEN, (char *)IpcIoPopString(reply, &len)); 520 } 521 522 static BOOL SyncCall(IUnknown *iUnknown, struct Payload *payload) 523 { 524 DemoClientProxy *proxy = (DemoClientProxy *)iUnknown; 525 IpcIo request; 526 char data[MAX_DATA_LEN]; 527 IpcIoInit(&request, data, MAX_DATA_LEN, 0); 528 IpcIoPushInt32(&request, payload->id); 529 IpcIoPushInt32(&request, payload->value); 530 IpcIoPushString(&request, payload->name); 531 int ret = proxy->Invoke((IClientProxy *)proxy, ID_SYNCCALL, &request, data, Callback); 532 data[MAX_DATA_LEN - 1] = 0; 533 HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Remote response is %s!", pthread_self(), data); 534 return ret == EC_SUCCESS; 535 } 536 537 struct CurrentNotify { 538 IOwner notify; 539 INotifyFunc handler; 540 }; 541 542 static int CurrentCallback(IOwner owner, int code, IpcIo *reply) 543 { 544 struct CurrentNotify *notify = (struct CurrentNotify *)owner; 545 size_t len = 0; 546 char *response = (char *)IpcIoPopString(reply, &len); 547 HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Notify Remote response is %s!", pthread_self(), response); 548 notify->handler(notify->notify, response); 549 return EC_SUCCESS; 550 } 551 552 static BOOL AsyncCallBack(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler) 553 { 554 struct CurrentNotify owner = {notify, handler}; 555 DemoClientProxy *proxy = (DemoClientProxy *)iUnknown; 556 IpcIo request; 557 char data[MAX_DATA_LEN]; 558 IpcIoInit(&request, data, MAX_DATA_LEN, 0); 559 IpcIoPushString(&request, buff); 560 int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCCALLBACK, &request, &owner, CurrentCallback); 561 return ret == EC_SUCCESS; 562 } 563 ``` 564 565- 实现客户端代理的工厂方法: 566 567 ``` 568 void *DEMO_CreatClient(const char *service, const char *feature, uint32 size) 569 { 570 (void)service; 571 (void)feature; 572 uint32 len = size + sizeof(DemoClientEntry); 573 uint8 *client = malloc(len); 574 (void)memset_s(client, len, 0, len); 575 DemoClientEntry *entry = (DemoClientEntry *)&client[size]; 576 entry->ver = ((uint16)CLIENT_PROXY_VER | (uint16)DEFAULT_VERSION); 577 entry->ref = 1; 578 entry->iUnknown.QueryInterface = IUNKNOWN_QueryInterface; 579 entry->iUnknown.AddRef = IUNKNOWN_AddRef; 580 entry->iUnknown.Release = IUNKNOWN_Release; 581 entry->iUnknown.Invoke = NULL; 582 entry->iUnknown.AsyncCall = AsyncCall; 583 entry->iUnknown.AsyncTimeCall = AsyncTimeCall; 584 entry->iUnknown.SyncCall = SyncCall; 585 entry->iUnknown.AsyncCallBack = AsyncCallBack; 586 return client; 587 } 588 void DEMO_DestroyClient(const char *service, const char *feature, void *iproxy) 589 { 590 free(iproxy); 591 } 592 ``` 593 594- 将客户端代理的工厂方法注册到SAMGR: 595 596 ``` 597 SAMGR_RegisterFactory(EXAMPLE_SERVICE, EXAMPLE_FEATURE, DEMO_CreatClient, DEMO_DestroyClient); 598 ``` 599 600- 获取跨进程服务的对外接口: 601 602 ``` 603 DemoClientProxy *demoApi = NULL; 604 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE); 605 if (iUnknown == NULL) { 606 return NULL; 607 } 608 int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi); 609 if (result != 0 || demoApi == NULL) { 610 return NULL; 611 } 612 ``` 613 614- 调用跨进程服务的客户端代理接口: 615 616 ``` 617 if (demoApi->AsyncCallBack == NULL) { 618 return NULL; 619 } 620 demoApi->AsyncCallBack((IUnknown *)demoApi, 621 "I wanna async call callback good result!", NULL, AsyncHandler); 622 ``` 623 624- 释放接口: 625 626 ``` 627 int32 ref = demoApi->Release((IUnknown *)demoApi); 628 ``` 629 630 631## 相关仓<a name="section10365113863719"></a> 632 633系统服务管理子系统 634 635[**systemabilitymgr\_samgr\_lite**](https://gitee.com/openharmony/systemabilitymgr_samgr_lite) 636 637[systemabilitymgr\_samgr](https://gitee.com/openharmony/systemabilitymgr_samgr) 638 639[systemabilitymgr\_safwk](https://gitee.com/openharmony/systemabilitymgr_safwk) 640 641[systemabilitymgr\_safwk\_lite](https://gitee.com/openharmony/systemabilitymgr_safwk_lite) 642 643