- IDL 工具
1.openharmony IDL工具
在OpenHarmony中,当应用/系统服务的客户端和服务端进行IPC(Inter-Process Communication)跨线程通信时,需要定义双方都认可的接口,以保障双方可以成功通信,OpenHarmony IDL(Interface Definition Language)则是一种定义此类接口的工具。OpenHarmony IDL先把需要传递的对象分解成操作系统能够理解的基本类型,并根据开发者的需要封装跨边界的对象。
OpenHarmony IDL接口描述语言主要用于:
-
声明系统服务对外提供的服务接口,根据接口声明在编译时生成跨进程调用(IPC)或跨设备调用(RPC)的代理(Proxy)和桩(Stub)的C/C++代码或JS/TS代码。
-
声明Ability对外提供的服务接口,根据接口声明在编译时生成跨进程调用(IPC)或跨设备调用(RPC)的代理(Proxy)和桩(Stub)的C/C++代码或JS/TS代码。
使用OpenHarmony IDL接口描述语言声明接口具有以下优点:
-
OpenHarmony IDL中是以接口的形式定义服务,可以专注于定义而隐藏实现细节。
-
OpenHarmony IDL中定义的接口可以支持跨进程调用或跨设备调用。根据OpenHarmony IDL中的定义生成的信息或代码可以简化跨进程或跨设备调用接口的实现。
2.开发步骤:参考IDL开发指南
2.1.获取IDL工具
在linux系统,下载OpenHarmony的两个仓:ability_idl_tool代码仓、third_party_bounds_checking_function代码仓。进入ability_idl_tool代码仓,在Makefile所在目录执行make命令(注意修改MakefileLinux中关于bounds_checking_function的相对位置)。make执行完成后,在当前目录下会生成idl-gen可执行文件,可用于idl文件本地调试。
代码下载:
- https://gitee.com/openharmony/ability_idl_tool.git
- https://gitee.com/openharmony/third_party_bounds_checking_function.git
执行编译:
- 将ability_idl_tool(master分支)和third_party_bounds_checking_function下载到同级目录,然后创建third_party目录,并把third_party_bounds_checking_function改为bounds_checking_function拷贝到third_party目录。
- 修改MakefileLinux:
c
14 #BOUNDS_CHECK_DIR := $(abspath ../../../third_party/bounds_checking_function)
15 BOUNDS_CHECK_DIR := $(abspath ../third_party/bounds_checking_function)
44 #BOUNDS_CHECK_SOURCE_DIR := $(abspath ../../../third_party/bounds_checking_function/src)
45 BOUNDS_CHECK_SOURCE_DIR := $(abspath ../third_party/bounds_checking_function/src)
- 执行make,生成idl-gen。
2.2.创建.idl文件
构建一个名为IIdlTestService.idl的文件,内容如下:
c
16 interface OHOS.IIdlTestService {
17 void TestIntTransaction([in] int val);
18 void TestStringTransaction([in] String val);
19 }
在idl的可执行文件所在文件夹下执行命令:
ability_idl_tool$ ./idl-gen -gen-ts -d IIdlTestServiceTs -c IIdlTestServiceTs/IIdlTestService.idl
-d后的dir为目标输出目录,以输出文件夹名为IIdlTestServiceTs为例,在idl可执行文件所在目录下执行./idl-gen -gen-ts -d IIdlTestServiceTs -c IIdlTestServiceTs/IIdlTestService.idl,将会在执行环境的IIdlTestServiceTs目录中生成接口文件、Stub文件、Proxy文件。
注意:生成的接口类文件名称和.idl文件名称保持一致,否则会生成代码时会出现错误。
以IIdlTestServiceTs为例,其目录结构应类似于:
c
ability_idl_tool/IIdlTestServiceTs$ ls -lh
total 16K
-rw-rw-r-- 1 zhaoxiao zhaoxiao 3.1K 1月 15 18:26 idl_test_service_proxy.ts
-rw-rw-r-- 1 zhaoxiao zhaoxiao 2.8K 1月 15 18:26 idl_test_service_stub.ts
-rw-rw-r-- 1 zhaoxiao zhaoxiao 736 1月 15 18:25 IIdlTestService.idl
-rw-rw-r-- 1 zhaoxiao zhaoxiao 963 1月 15 18:26 i_idl_test_service.ts
2.3.服务端公开接口
OpenHarmony IDL工具生成的Stub类是接口类的抽象实现,并且会声明.idl文件中的所有方法。
c
idl_test_service_stub.ts:
16 import {testIntTransactionCallback} from "./i_idl_test_service";
17 import {testStringTransactionCallback} from "./i_idl_test_service";
18 import IIdlTestService from "./i_idl_test_service";
19 import rpc from "@ohos.rpc";
20
21 export default class IdlTestServiceStub extends rpc.RemoteObject implements IIdlTestService {
22 constructor(des: string) {
23 super(des);
24 }
25
26 async onRemoteMessageRequest(code: number, data:rpc.MessageSequence, reply:rpc.MessageSequence, option:rpc.MessageOption): Promise<boolean> {
27 let localDescriptor = this.getDescriptor();
28 let remoteDescriptor = data.readInterfaceToken();
29 if (localDescriptor !== remoteDescriptor) {
30 console.log("invalid interfaceToken");
31 return false;
32 }
33 console.log("onRemoteMessageRequest called, code = " + code);
34 switch(code) {
35 case IdlTestServiceStub.COMMAND_TEST_INT_TRANSACTION: {
36 let valVar = data.readInt();
37 let promise = new Promise<void>((resolve,reject) => {
38 this.testIntTransaction(valVar, (errCode) => {
39 reply.writeInt(errCode);
40 resolve();
41 });
42 });
43 await promise;
44 return true;
45 }
46 case IdlTestServiceStub.COMMAND_TEST_STRING_TRANSACTION: {
47 let valVar = data.readString();
48 let promise = new Promise<void>((resolve,reject) => {
49 this.testStringTransaction(valVar, (errCode) => {
50 reply.writeInt(errCode);
51 resolve();
52 });
53 });
54 await promise;
55 return true;
56 }
57 default: {
58 console.log("invalid request code" + code);
59 break;
60 }
61 }
62 return false;
63 }
64
65 testIntTransaction(val: number, callback: testIntTransactionCallback): void{}
66 testStringTransaction(val: string, callback: testStringTransactionCallback): void{}
67
68 static readonly COMMAND_TEST_INT_TRANSACTION = 1;
69 static readonly COMMAND_TEST_STRING_TRANSACTION = 2;
70 }
开发者需要继承.idl文件中定义的接口类并实现其中的方法。在本示例中,继承IdlTestServiceStub接口类并实现了其中的testIntTransaction、testStringTransaction方法。具体的示例代码如下:
c
import {testIntTransactionCallback} from "./i_idl_test_service"
import {testStringTransactionCallback} from "./i_idl_test_service"
import IdlTestServiceStub from "./idl_test_service_stub"
class IdlTestImp extends IdlTestServiceStub {
testIntTransaction(data: number, callback: testIntTransactionCallback): void
{
callback(0, data + 1);
}
testStringTransaction(data: string, callback: testStringTransactionCallback): void
{
callback(0);
}
}
refer to
-https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/IDL/idl-guidelines.md#31-c开发步骤