1# IDL语法 2 3## 接口定义 4 5使用 interface 定义 6 7```cpp 8package OHOS.One; 9 10option_stub_hooks on; // 开启钩子功能 11interface OHOS.Two.Test { 12 13} 14``` 15 16注意: 17 1.文件名必须与接口名称一致,如这里的文件应该命名为Test.idl; 18 2.可以使用 package 或 接口名前定义 两种方式设置接口的命名空间;当同时定义时,后者优先级更高。如上面实例 OHOS.Two 命名空间将会生效。 19 20## 数据类型 21 22### 基础数据类型 23| IDL文件写法 | 对应cpp的类型 | 功能和规格限制 | 生成的序列化代码 | 生成的反序列化代码 | 24|-----------------|--------------|--------|-----------------------------------|-------------------------------------| 25| void | 默认为IPC错误码 | | 无 | 无 | 26| boolean | bool | | WriteInt32 | ReadInt32 | 27| byte | int8_t | | WriteInt32 | ReadInt32 | 28| short | short | | WriteInt32 | ReadInt32 | 29| int | int32_t | | WriteInt32 | ReadInt32 | 30| long | int64_t | | WriteInt64 | ReadInt64 | 31| float | float | | WriteFloat | ReadFloat | 32| double | double | | WriteDouble | ReadDouble | 33| char | char | | WriteInt32 | ReadInt32 | 34| String | std::string | | WriteString16(Str8ToStr16(inParam)) | Str16ToStr8(data.ReadString16()) | 35| unsigned char | uint8_t | | WriteUint8 | ReadUint8 | 36| unsigned short | uint16_t | | WriteUint16 | ReadUint16 | 37| unsigned int | uint32_t | | WriteUint32 | ReadUint32 | 38| unsigned long | uint64_t | | WriteUint64 | ReadUint64 | 39| FileDescriptor | int | | WriteFileDescriptor | ReadFileDescriptor | 40| T[] ,其中T表示其他数据类型 | std::vector<T> | VECTOR_MAX_SIZE = 102400 | WriteInt32 (数据的大小),<br>然后通过 for 循环逐项序列化 | ReadInt32 (数据的大小),<br>然后通过 for 循环逐项反序列化 | 41| List<T> <br>其中T表示其他数据类型 | std::vector<T> | LIST_MAX_SIZE = 102400 | WriteInt32 (数据的大小),<br>然后通过 for 循环逐项序列化 | ReadInt32 (数据的大小),<br>然后通过 for 循环逐项反序列化 | 42| Map<T1, T2> <br>其中T1和T2表示其他数据类型 | std::unordered_map<T1, T2> | MAP_MAX_SIZE = 102400 | WriteInt32 (数据的大小),<br>然后逐项序列化 map 的 key 和 value | ReadInt32 (数据的大小),<br>然后逐项反序列化 map 的 key 和 value,并组成新的 map | 43| IRemoteObkect <br>需要在接口类上方声明:<br>sequenceable OHOS.IRemoteObject; | sptr<IRemoteObject> | | WriteRemoteObject | ReadRemoteObject | 44 45 46 47### 自定义序列化对象:用sequenceable声明 48 49业务方在实现自定义对象时需要继承Parcelable,实现Marshalling和Unmarshalling函数。 50 51| IDL文件写法 | 对应cpp的类型 | 生成的.h中对头文件、命名空间的处理 | 生成的序列化代码 | 生成的反序列化代码 | 52| ------------------------------------------------------------ | ------------- | ----------------------------------------------------- | ------------------------- | ----------------------- | 53| sequencealbe test.MySeq1;<br />头文件与类名一致 | MySeq1 | #include “my_seq1.h”<br />using test::MySeq1; | WriteParcelable(&inParam) | ReadParcelable<myseq>() | 54| sequencealbe <br />FooMyseq..test.MySeq2;<br />指定头文件 | MySeq2 | #include “foo_my_seq2.h”<br />using test::MySeq2; | WriteParcelable(&inParam) | ReadParcelable<myseq>() | 55| sequencealbe <br />FooTest.MySeq..test.MySeq3;<br />指定头文件及其路径 | MySeq2 | #include “foo_test/my_seq.h”<br />using test::MySeq3; | WriteParcelable(&inParam) | ReadParcelable<myseq>() | 56 57 58 59### 自定义回调 60 61业务方在实现自定义回调时需要继承 IRemoteBroker 62 63| IDL文件写法 | 对应cpp的类型 | 生成的.h中对头文件、命名空间的处理 | 生成的序列化代码 | 生成的反序列化代码 | 64| ------------------------------------------------------ | ------------- | -------------------------------------------------- | -------------------------------------- | --------------------------------------------- | 65| interface test.MyIntf1;<br />头文件与类名一致 | sptr<MyIntf1> | #include “my_Intf1.h”<br />using test::MyIntf1; | WriteRemoteObject(inParam->AsObject()) | iface_cast<MyIntf1>(reply.ReadRemoteObject()) | 66| interface FooMyIntf..test.MyIntf2;<br />指定头文件路径 | MySeq2 | #include “foo_my_intf.h”<br />using test::MyIntf2; | WriteRemoteObject(inParam->AsObject()) | iface_cast<MyIntf1>(reply.ReadRemoteObject()) | 67 68 69 70### 复合数据类型 71 72复合数据类型定义在独立的idl文件中,通过import进行调用,在复杂类型idl文件开头定义命名空间,如:package OHOS.custom.idlFile; 73 74注:不支持在复合类型的idl文件中使用sequenceable 75 76| IDL文件写法 | 对应cpp的类型 | 生成的.h中对头文件、命名空间的处理 | 生成的序列化代码 | 生成的反序列化代码 | 77| ------------------------------------------------------------ | ------------- | ------------------------------------------------------------ | -------------------------------------- | --------------------------------------------- | 78| enum FooEnum {<br/> ENUM_ONE = 1,<br/> ENUM_TWO,<br/> }; | enum | enum class FooEnum : int32_t {<br/> ENUM_ONE = 1,<br/> ENUM_TWO,<br/>}; | WriteUint64 | ReadUint64 | 79| struct FooStruct {<br/> int id;<br/> String name;<br/> enum FooEnum type;<br/>}; | struct | struct FooStruct {<br/> int32_t id;<br/> std::string name;<br/> FooEnum type;<br/> sptr<IRemoteObject> caption;<br/>}; | 根据包含的类型对应生成Marshalling函数 | 根据包含的类型对应生成Unmarshalling函数 | 80| union FooUnion {<br/> enum FooEnum enumType;<br/> int unionInfo;<br/>}; | union | union FooUnion {<br/> FooEnum enumType;<br/> int32_t unionInfo;<br/>} __attribute__ ((aligned(8))); | WriteUnpadBuffer | ReadUnpadBuffer | 81 82 83 84### callback 85 86在接口前使用[callback]表示回调接口; 87 88| IDL文件写法 | 生成的代码示例 | 89| ------------------------------------------------------------ | ------------------- | 90| [callback] interface OHOS.fcallback.ICallback {<br/> void void_test_func();<br/>} | 生成代码同interface | 91 92 93 94## import 95 96import关键字用于idl文件关联解析其他idl文件。 97 98| IDL文件写法 | 功能和规格限制 | 99| ------------------------------------------------------------ | ------------------------------------------------------------ | 100| import相对路径、支持平级目录、上级目录和下级目录。如:<br /><br />import ../Types;<br />关联父目录下的Types.idl文件。<br /><br />import Callback/ICallback;<br />关联同级目录下的Callback目录下的ICallback.idl文件。 | 1.import的idl文件无需带“.idl”后缀<br />2.被import的idl文件只能是复杂类型idl文件回调idl文件;<br />3.只支持在接口idl文件或回调idl文件中使用import,不支持在复杂类型idl文件中使用import。 | 101 102 103 104## 方法修饰符 105 106在方法面前使用[],表示修饰方法的属性。可以多个方法修饰符同时使用,使用逗号分隔 107 108| 方法装饰器名称 | 功能和规格限制 | idl文件中的写法 | 生成的代码示例 | 109| -------------- | ------------------------------------------------------------ | ------------------- | ------------------------------------------------------------ | 110| oneway | 表示接口是异步 | [oneway] | 有oneway装饰:MseeageOption option(MessageOption::TF_ASYNC)<br />无oneway装饰:MessageOption option(MessageOption::TF_SYNC) | 111| cacheable | 表示缓存 | [cacheable 100] | 增加对ApiCacheManager相关接口的调用 | 112| ipccode | 用于指定IPC代码<br />最小值为1,最大值为16777215(0x00ffffff)<br />不能重复<br />支持十进制和十六进制<br />仅在SA模式生成cpp时生效,其他模式不支持 | [ipccode 20] | remote->SendRequest(static_cast<uint32_t>(IFooIpcCode::COMMAND_BOOL_TEST_FUNC), data, reply, option); | 113| ipcincapacity | 用于指定Proxy类的IPC容量。<br />单位为KB;<br />最小值为1,最大值为1310071<br />只支持十进制<br />仅在SA模式生成cpp时生效,其他模式不支持 | [ipcincapacity 10] | if (!data.SetMaxCapacity(CAPACITY_BOOL_TEST_FUNC_10)) {<br /> return ERR_INVALID_VALUE;<br />} | 114| ipcoutcapacity | 用于指定Stub类的IPC容量,<br />规格限制同ipcincapacity | [ipcoutcapacity 20] | if (!data.SetMaxCapacity(CAPACITY_BOOL_TEST_FUNC_10)) {<br /> return ERR_INVALID_VALUE;<br />} | 115 116 117 118## 参数修饰符 119 120在方法的参数前使用[],表示修饰参数为入参、出参或既是入参又是出参。 121 122| 方法装饰器名称 | 功能 | idl文件中的写法 | 生成的代码示例 | 123| -------------- | :------------------- | --------------- | ------------------------------------------------------------ | 124| in | 表示入参 | [in] | 在Proxy端进行序列化,在Stub端进行反序列化 | 125| out | 表示出参 | [out] | 在Proxy端调用SendRequset需要反序列化,<br />在Stub端调用方法后需要序列化 | 126| inout | 表示既是入参又是出参 | [inout] | 在Proxy端进行序列化,执行SendRequset后再做反序列化,<br />在Stub端进行反序列化,调用方法后在再进行序列化。 | 127 128不同的参数修饰符会影响生成代码的参数有无 “const” "&" 等,可在下面路径对应的参数下找到对应的生成规则。 129 130比如seq类型对应路径为 code/foundation/ability/idl_tool/idl_tool_2/codegen/SA/type/sa_seq_type_emitter.cpp: 131```cpp 132switch (mode) { 133 case TypeMode::PARAM_IN: 134 return StringHelper::Format("const %s&", typeName_.c_str()); 135 case TypeMode::PARAM_INOUT: 136 case TypeMode::PARAM_OUT: 137 return StringHelper::Format("%s&", typeName_.c_str()); 138 case TypeMode::NO_MODE: 139 case TypeMode::LOCAL_VAR: 140 return typeName_; 141 default: 142 return "unknown type"; 143} 144``` 145 146 147 148## 综合使用示例 149 150IFooCustom.idl: 151```cpp 152enum FooEnum { 153 ENUM_ONE = 1, 154 ENUM_TWO = 2, 155 ENUM_NESTING = (ENUM_ONE << ENUM_TWO) 156}; 157 158struct FooStruct { 159 int id; 160 String name; 161 enum FooEnum type; 162 IRemoteObject caption; 163}; 164 165union FooUnion { 166 enum FooEnum enumType; 167 int unionInfo; 168}; 169 170struct RequestInfo { 171 unsigned char[] initData; 172 Map<String, String> optionalData; 173}; 174``` 175 176Callback/ICallback.idl: 177```cpp 178package OHOS.fcallback; 179 180[callback] interface OHOS.fcallback.ICallback { 181 void void_test_func(); 182} 183``` 184 185Test.idl: 186```cpp 187import ../IFooCustom; 188import ../fcallback/ICallback; 189import callback/IFoocallback; 190 191interface OHOS.test.IFoo { 192 FooEnum enum_test_func([in] FooEnum inParam, [out] FooEnum outParam, [inout] FooEnum inoutParam); 193 FooStruct struct_test_func([in] FooStruct inParam, [out] FooStruct outParam, [inout] RequestInfo inoutParam); 194 FooUnion union_test_func([in] FooUnion inParam, [out] FooUnion outParam, [inout] FooUnion inoutParam); 195 IFoocallback callback_test_func([in] IFoocallback inParam, [out] IFoocallback outParam, [inout] IFoocallback inoutParam); 196 ICallback callback_test_func2([in] ICallback inParam, [out] ICallback outParam, [inout] ICallback inoutParam); 197 void ApplyQuickFix([in] String[] quickFixFiles, [in] boolean isDebug); 198 void GetAllAppSuspendState([in] Map<int, FooStruct> inApp, [out] Map<int, FooStruct> outApp); 199} 200```