Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Docs
提交
59a76239
D
Docs
项目概览
OpenHarmony
/
Docs
大约 2 年 前同步成功
通知
161
Star
293
Fork
28
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
Docs
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
59a76239
编写于
11月 24, 2022
作者:
O
openharmony_ci
提交者:
Gitee
11月 24, 2022
浏览文件
操作
浏览文件
下载
差异文件
!11262 idl资料优化
Merge pull request !11262 from chenyuyan/idlDocs
上级
007cd3a7
f1b9a50f
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
29 addition
and
308 deletion
+29
-308
zh-cn/application-dev/IDL/figures/SDKpath.png
zh-cn/application-dev/IDL/figures/SDKpath.png
+0
-0
zh-cn/application-dev/IDL/figures/SDKpath2.png
zh-cn/application-dev/IDL/figures/SDKpath2.png
+0
-0
zh-cn/application-dev/IDL/idl-guidelines.md
zh-cn/application-dev/IDL/idl-guidelines.md
+29
-308
未找到文件。
zh-cn/application-dev/IDL/figures/SDKpath.png
0 → 100644
浏览文件 @
59a76239
96.1 KB
zh-cn/application-dev/IDL/figures/SDKpath2.png
0 → 100644
浏览文件 @
59a76239
94.0 KB
zh-cn/application-dev/IDL/idl-guidelines.md
浏览文件 @
59a76239
...
...
@@ -149,198 +149,53 @@ OpenHarmony IDL容器数据类型与Ts数据类型、C++数据类型的对应关
## 开发步骤
### C++开发步骤
### IDL工具的获取
首先,打开DevEco Studio—>Tools—>SDK Manager,查看OpenHarmony SDK的本地安装路径,此处以DevEco Studio 3.0.0.993版本为例,查看方式如下图所示。


#### 创建.idl文件
开发者可以使用C++编程语言构建.idl文件。.idl示例如下:
进入对应路径后,查看toolchains->3.x.x.x(对应版本号命名文件夹)下是否存在idl工具的可执行文件。
```
cpp
interface
OHOS
.
IIdlTestService
{
int
TestIntTransaction
([
in
]
int
data
);
void
TestStringTransaction
([
in
]
String
data
);
}
```
> **注意**:请保证使用最新版的SDK,版本老旧可能导致部分语句报错。
使用者通过执行命令 “./idl -gen-cpp -d dir -c dir/iTest.idl” (-d为输出目录)在执行环境的dir目录中生成接口文件、Stub文件、Proxy文件。生成的接口类文件名称和.idl文件名称保持一致,区别在于其使用.h和.cpp扩展名。例如,IIdlTestService.idl 生成的文件名是 i_idl_test_service.h、idl_test_service_proxy.h、idl_test_service_stub.h、idl_test_service_proxy.cpp、idl_test_service_stub.cpp
。
若不存在,可对应版本前往
[
docs仓版本目录
](
https://gitee.com/openharmony/docs/tree/master/zh-cn/release-notes
)
下载SDK包,以
[
3.2Beta3版本
](
https://gitee.com/openharmony/docs/blob/master/zh-cn/release-notes/OpenHarmony-v3.2-beta3.md#%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96
)
为例,可通过镜像站点获取
。
#### 服务端公开接口
关于如何替换DevEco Studio的SDK包具体操作,参考
[
full-SDK替换指南
](
https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/full-sdk-switch-guide.md#full-sdk%E6%9B%BF%E6%8D%A2%E6%8C%87%E5%8D%97
)
中的替换方法。
OpenHarmony IDL工具生成的Stub类是接口类的抽象实现,并且会声明.idl文件中的所有方法。
得到idl工具的可执行文件后,根据具体场景进行后续开发步骤。
```
cpp
#ifndef OHOS_IDLTESTSERVICESTUB_H
#define OHOS_IDLTESTSERVICESTUB_H
#include <iremote_stub.h>
#include "iidl_test_service.h"
namespace
OHOS
{
class
IdlTestServiceStub
:
public
IRemoteStub
<
IIdlTestService
>
{
public:
int
OnRemoteRequest
(
/* [in] */
uint32_t
code
,
/* [in] */
MessageParcel
&
data
,
/* [out] */
MessageParcel
&
reply
,
/* [in] */
MessageOption
&
option
)
override
;
private:
static
constexpr
int
COMMAND_TEST_INT_TRANSACTION
=
MIN_TRANSACTION_ID
+
0
;
static
constexpr
int
COMMAND_TEST_STRING_TRANSACTION
=
MIN_TRANSACTION_ID
+
1
;
};
}
// namespace OHOS
#endif // OHOS_IDLTESTSERVICESTUB_H
```
### TS开发步骤
开发者需要继承.idl文件中定义的接口类并实现其中的方法,同时在服务侧初始化时需要将定义的服务注册至SAMGR中,在本示例中,TestService类继承了IdlTestServiceStub接口类并实现了其中的TestIntTransaction和TestStringTransaction方法。具体的示例代码如下:
#### 创建.idl文件
```
cpp
#ifndef OHOS_IPC_TEST_SERVICE_H
#define OHOS_IPC_TEST_SERVICE_H
#include "hilog/log.h"
#include "log_tags.h"
#include "idl_test_service_stub.h"
namespace
OHOS
{
class
TestService
:
public
IdlTestServiceStub
{
public:
TestService
();
~
TestService
();
static
int
Instantiate
();
ErrCode
TestIntTransaction
(
int
data
,
int
&
rep
)
override
;
ErrCode
TestStringTransaction
(
const
std
::
string
&
data
)
override
;
private:
static
constexpr
HiviewDFX
::
HiLogLabel
LABEL
=
{
LOG_CORE
,
LOG_ID_IPC
,
"TestService"
};
};
}
// namespace OHOS
#endif // OHOS_IPC_TEST_SERVICE_H
```
开发者可以使用TS编程语言构建.idl文件。
注册服务的示例代码如下:
例如,此处构建一个名为IIdlTestService.idl的文件,文件内具体内容如下:
```
cpp
#include "test_service.h"
#include <string_ex.h>
#include "if_system_ability_manager.h"
#include "ipc_debug.h"
#include "ipc_skeleton.h"
#include "iservice_registry.h"
#include "system_ability_definition.h"
namespace
OHOS
{
using
namespace
OHOS
::
HiviewDFX
;
int
TestService
::
Instantiate
()
{
ZLOGI
(
LABEL
,
"%{public}s call in"
,
__func__
);
auto
saMgr
=
SystemAbilityManagerClient
::
GetInstance
().
GetSystemAbilityManager
();
if
(
saMgr
==
nullptr
)
{
ZLOGE
(
LABEL
,
"%{public}s:fail to get Registry"
,
__func__
);
return
-
ENODEV
;
}
sptr
<
IRemoteObject
>
newInstance
=
new
TestService
();
int
result
=
saMgr
->
AddSystemAbility
(
IPC_TEST_SERVICE
,
newInstance
);
ZLOGI
(
LABEL
,
"%{public}s: IPC_TEST_SERVICE result = %{public}d"
,
__func__
,
result
);
return
result
;
}
TestService
::
TestService
()
{
}
TestService
::~
TestService
()
{
}
ErrCode
TestService
::
TestIntTransaction
(
int
data
,
int
&
rep
)
{
ZLOGE
(
LABEL
,
" TestService:read from client data = %{public}d"
,
data
);
rep
=
data
+
data
;
return
ERR_NONE
;
}
ErrCode
TestService
::
TestStringTransaction
(
const
std
::
string
&
data
)
{
ZLOGE
(
LABEL
,
"TestService:read string from client data = %{public}s"
,
data
.
c_str
());
return
data
.
size
();
}
}
// namespace OHOS
interface
OHOS
.
IIdlTestService
{
int
TestIntTransaction
([
in
]
int
data
);
void
TestStringTransaction
([
in
]
String
data
);
}
```
#### 客户端调用IPC方法
C++客户端通常通过SAMGR获取系统中定义的服务代理,随后即可正常调用proxy提供的接口。示例代码如下:
在idl的可执行文件所在文件夹下执行命令
`idl -gen-ts -d dir -c dir/IIdlTestService.idl`
。
```
cpp
#include "test_client.h"
#include "if_system_ability_manager.h"
#include "ipc_debug.h"
#include "ipc_skeleton.h"
#include "iservice_registry.h"
#include "system_ability_definition.h"
namespace
OHOS
{
int
TestClient
::
ConnectService
()
{
auto
saMgr
=
SystemAbilityManagerClient
::
GetInstance
().
GetSystemAbilityManager
();
if
(
saMgr
==
nullptr
)
{
ZLOGE
(
LABEL
,
"get registry fail"
);
return
-
1
;
}
-d后的dir为目标输出目录,以输出文件夹名为IIdlTestServiceTs为例,在idl可执行文件所在目录下执行
`idl -gen-ts -d IIdlTestServiceTs -c IIdlTestServiceTs/IIdlTestService.idl`
,将会在执行环境的dir目录(即IIdlTestServiceTs目录)中生成接口文件、Stub文件、Proxy文件。
sptr
<
IRemoteObject
>
object
=
saMgr
->
GetSystemAbility
(
IPC_TEST_SERVICE
);
if
(
object
!=
nullptr
)
{
ZLOGE
(
LABEL
,
"Got test Service object"
);
testService_
=
(
new
(
std
::
nothrow
)
IdlTestServiceProxy
(
object
));
}
> **注意**:生成的接口类文件名称和.idl文件名称保持一致,否则会生成代码时会出现错误。
if
(
testService_
==
nullptr
)
{
ZLOGE
(
LABEL
,
"Could not find Test Service!"
);
return
-
1
;
}
return
0
;
}
以名为
`IIdlTestService.idl`
的.idl文件、目标输出文件夹为IIdlTestServiceTs为例,其目录结构应类似于:
void
TestClient
::
StartIntTransaction
()
{
if
(
testService_
!=
nullptr
)
{
ZLOGE
(
LABEL
,
"StartIntTransaction"
);
[[
maybe_unused
]]
int
result
=
0
;
testService_
->
TestIntTransaction
(
1234
,
result
);
// 1234 : test number
ZLOGE
(
LABEL
,
"Rec result from server %{public}d."
,
result
);
}
}
void
TestClient
::
StartStringTransaction
()
{
if
(
testService_
!=
nullptr
)
{
ZLOGI
(
LABEL
,
"StartIntTransaction"
);
testService_
->
TestStringTransaction
(
"IDL Test"
);
}
}
}
// namespace OHOS
```
### TS开发步骤
#### 创建.idl文件
开发者可以使用TS编程语言构建.idl文件。.idl示例如下:
```
ts
interface
OHOS
.
IIdlTestService
{
int
TestIntTransaction
([
in
]
int
data
);
void
TestStringTransaction
([
in
]
String
data
);
}
├── IIdlTestServiceTs # idl代码输出文件夹
│ ├── i_idl_test_service.ts # 生成文件
│ ├── idl_test_service_proxy.ts # 生成文件
│ ├── idl_test_service_stub.ts # 生成文件
│ └── IIdlTestService.idl # 构造的.idl文件
└── idl.exe # idl的可执行文件
```
使用者通过执行命令 “./idl -c IIdlTestService.idl -gen-ts -d /data/ts/” (-d为输出目录)在执行环境的/data/ts/目录中生成接口文件、Stub文件、Proxy文件。生成的接口类文件名称和.idl文件名称保持一致,区别在于其使用.ts扩展名。例如,IIdlTestService.idl 生成的文件名是 i_idl_test_service.ts、idl_test_service_proxy.ts、idl_test_service_stub.ts。
#### 服务端公开接口
OpenHarmony IDL工具生成的Stub类是接口类的抽象实现,并且会声明.idl文件中的所有方法。
...
...
@@ -356,8 +211,8 @@ export default class IdlTestServiceStub extends rpc.RemoteObject implements IIdl
super
(
des
);
}
onRemoteRequest
(
code
:
number
,
data
,
reply
,
option
):
boolean
{
console
.
log
(
"
onRemoteRequest called, code =
"
+
code
);
async
onRemoteRequestEx
(
code
:
number
,
data
,
reply
,
option
):
Promise
<
boolean
>
{
console
.
log
(
"
onRemoteRequest
Ex
called, code =
"
+
code
);
switch
(
code
)
{
case
IdlTestServiceStub
.
COMMAND_TEST_INT_TRANSACTION
:
{
let
_data
=
data
.
readInt
();
...
...
@@ -529,137 +384,3 @@ export default class MySequenceable {
private
str
;
}
```
## C++与TS互通开发步骤
### TS Proxy与C++ Stub开发步骤
#### C++端提供服务对象
1.
如上所述C++开发步骤,开发者使用C++编程语言构建.idl文件,通过命令生成接口、Stub文件、Proxy文件。
2.
开发者创建服务对象,并继承C++ Stub文件中定义的接口类并实现其中的方法,例如:
```
cpp
class
IdlTestServiceImpl
:
public
IdlTestServiceStub
{
public:
IdlTestServiceImpl
()
=
default
;
virtual
~
IdlTestServiceImpl
()
=
default
;
ErrCode
TestIntTransaction
(
int
_data
,
int
&
result
)
override
{
result
=
256
;
return
ERR_OK
;
}
ErrCode
TestStringTransaction
(
const
std
::
string
&
_data
)
override
{
return
ERR_OK
;
}
};
```
#### C++端提供napi接口
C++需要通过napi的方式,把C++服务对象提供给TS端,例如:C++端提供一个GetNativeObject方法,方法里创建IdlTestServiceImpl实例,通过NAPI_ohos_rpc_CreateJsRemoteObject方法,创建出一个JS远程对象供TS应用使用,如下:
```
cpp
NativeValue
*
GetNativeObject
(
NativeEngine
&
engine
,
NativeCallbackInfo
&
info
)
{
sptr
<
IdlTestServiceImpl
>
impl
=
new
IdlTestServiceImpl
();
napi_value
napiRemoteObject
=
NAPI_ohos_rpc_CreateJsRemoteObject
(
reinterpret_cast
<
napi_env
>
(
&
engine
),
impl
);
NativeValue
*
nativeRemoteObject
=
reinterpret_cast
<
NativeValue
*>
(
napiRemoteObject
);
return
nativeRemoteObject
;
}
```
#### TS端提供Proxy对象
如上所述TS开发步骤,开发者使用TS编程语言构建.idl文件,通过命令生成接口、Stub文件、Proxy文件。Proxy文件例如:
```
ts
import
{
testIntTransactionCallback
}
from
"
./i_idl_test_service
"
;
import
{
testStringTransactionCallback
}
from
"
./i_idl_test_service
"
;
import
IIdlTestService
from
"
./i_idl_test_service
"
;
import
rpc
from
"
@ohos.rpc
"
;
export
default
class
IdlTestServiceProxy
implements
IIdlTestService
{
constructor
(
proxy
)
{
this
.
proxy
=
proxy
;
}
testIntTransaction
(
data
:
number
,
callback
:
testIntTransactionCallback
):
void
{
let
_option
=
new
rpc
.
MessageOption
();
let
_data
=
new
rpc
.
MessageParcel
();
let
_reply
=
new
rpc
.
MessageParcel
();
_data
.
writeInt
(
data
);
this
.
proxy
.
sendRequest
(
IdlTestServiceProxy
.
COMMAND_TEST_INT_TRANSACTION
,
_data
,
_reply
,
_option
).
then
(
function
(
result
)
{
if
(
result
.
errCode
==
0
)
{
let
_errCode
=
result
.
reply
.
readInt
();
if
(
_errCode
!=
0
)
{
let
_returnValue
=
undefined
;
callback
(
_errCode
,
_returnValue
);
return
;
}
let
_returnValue
=
result
.
reply
.
readInt
();
callback
(
_errCode
,
_returnValue
);
}
else
{
console
.
log
(
'
sendRequest failed, errCode:
'
+
result
.
errCode
);
}
})
}
testStringTransaction
(
data
:
string
,
callback
:
testStringTransactionCallback
):
void
{
let
_option
=
new
rpc
.
MessageOption
();
let
_data
=
new
rpc
.
MessageParcel
();
let
_reply
=
new
rpc
.
MessageParcel
();
_data
.
writeString
(
data
);
this
.
proxy
.
sendRequest
(
IdlTestServiceProxy
.
COMMAND_TEST_STRING_TRANSACTION
,
_data
,
_reply
,
_option
).
then
(
function
(
result
)
{
if
(
result
.
errCode
==
0
)
{
let
_errCode
=
result
.
reply
.
readInt
();
callback
(
_errCode
);
}
else
{
console
.
log
(
'
sendRequest failed, errCode:
'
+
result
.
errCode
);
}
})
}
static
readonly
COMMAND_TEST_INT_TRANSACTION
=
1
;
static
readonly
COMMAND_TEST_STRING_TRANSACTION
=
2
;
private
proxy
}
```
#### TS与C++实现互通
1.
TS应用调用napi接口获取C++服务的远程对象
2.
构建TS Proxy对象,并把C++服务的远程对象传递给它
3.
此时开发者通过TS Proxy对象调用.idl声明的方法,实现TS Proxy与C++ Stub的互通,示例如下:
```
ts
import
IdlTestServiceProxy
from
'
./idl_test_service_proxy
'
import
nativeMgr
from
'
nativeManager
'
;
function
testIntTransactionCallback
(
errCode
:
number
,
returnValue
:
number
)
{
console
.
log
(
'
errCode:
'
+
errCode
+
'
returnValue:
'
+
returnValue
);
}
function
testStringTransactionCallback
(
errCode
:
number
)
{
console
.
log
(
'
errCode:
'
+
errCode
);
}
function
jsProxyTriggerCppStub
()
{
let
nativeObj
=
nativeMgr
.
GetNativeObject
();
let
tsProxy
=
new
IdlTestServiceProxy
(
nativeObj
);
// invoke testIntTransaction
tsProxy
.
testIntTransaction
(
10
,
testIntTransactionCallback
);
// invoke testStringTransaction
tsProxy
.
testStringTransaction
(
'
test
'
,
testIntTransactionCallback
);
}
```
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录