未验证 提交 57dde419 编写于 作者: O openharmony_ci 提交者: Gitee

!12681 翻译完成:11262+12031 idl资料优化

Merge pull request !12681 from wusongqing/TR11262
......@@ -149,198 +149,53 @@ The value of <*formal_param_attr*> can be **in**, **out**, or **inout**, indicat
## How to Develop
### Development Using C++
### Obtaining IDL
On DevEco Studio, choose **Tools > SDK Manager** to view the local installation path of the OpenHarmony SDK. The following figure uses DevEco Studio 3.0.0.993 as an example.
![SDKpath](./figures/SDKpath.png)
![SDKpath](./figures/SDKpath2.png)
#### Creating an IDL File
You can use C++ to create IDL files. An example IDL file is as follows:
Go to the local installation path, choose **toolchains > 3.x.x.x** (the folder named after the version number), and check whether the executable file of IDL exists.
```cpp
interface OHOS.IIdlTestService {
int TestIntTransaction([in] int data);
void TestStringTransaction([in] String data);
}
```
> **NOTE**: Use the SDK of the latest version. The use of an earlier version may cause errors in some statements.
You can run the **./idl -gen-cpp -d dir -c dir/iTest.idl** command (**-d** indicates the output directory) to generate the interface file, stub file, and proxy file in the **dir** directory in the execution environment. The names of the generated interface class files are the same as that of the IDL file, except that the file name extensions are **.h** and **.cpp**. For example, the files generated for **IIdlTestService.idl** are **i_idl_test_service.h**, **idl_test_service_proxy.h**, **idl_test_service_stub.h**, **idl_test_service_proxy.cpp**, and **idl_test_service_stub.cpp**.
If the executable file does not exist, download the SDK package from the mirror as instructed in the [Release Notes](../../release-notes). The following uses the [3.2 Beta3](../../release-notes/OpenHarmony-v3.2-beta3.md#acquiring-source-code-from-mirrors) as an example.
#### Exposing Interfaces on the Server
For details about how to replace the SDK package, see [Guide to Switching to Full SDK](../quick-start/full-sdk-switch-guide.md).
The stub class generated by IDL is an abstract implementation of the interface class and declares all methods in the IDL file.
After obtaining the executable file, perform subsequent development steps based on your scenario.
```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
```
### Development Using TS
You need to inherit the interface class defined in the IDL file and implement the methods in the class. In addition, you need to register the defined services with SAMGR during service initialization. In the following code snippet, **TestService** inherits the **IdlTestServiceStub** interface class and implements the **TestIntTransaction** and **TestStringTransaction** methods.
#### Creating an IDL File
```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
```
You can use TS to create IDL files.
The sample code for registering a service is as follows:
For example, create a file named **IIdlTestService.idl** with the following content:
```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);
}
```
#### Calling Methods from the Client for IPC
The C++ client obtains the service proxy defined in the system through SAMGR and then invokes the interface provided by the proxy. The sample code is as follows:
Run the **idl -gen-ts -d *dir* -c dir/IIdlTestService.idl** command in the folder where the executable file is located.
```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;
}
-*dir* next to **d** is the target output folder. For example, if the target output folder is **IIdlTestServiceTs**, run the **idl -gen-ts -d IIdlTestServiceTs -c IIdlTestServiceTs/IIdlTestService.idl** command in the folder where the executable file is located. The interface file, stub file, and proxy file are generated in the *dir* directory (**IIdlTestServiceTs** directory in this example) in the execution environment.
sptr<IRemoteObject> object = saMgr->GetSystemAbility(IPC_TEST_SERVICE);
if (object != nullptr) {
ZLOGE(LABEL, "Got test Service object");
testService_ = (new (std::nothrow) IdlTestServiceProxy(object));
}
> **NOTE**: The generated interface class file name must be the same as that of the .idl file. Otherwise, an error occurs during code generation.
if (testService_ == nullptr) {
ZLOGE(LABEL, "Could not find Test Service!");
return -1;
}
return 0;
}
For example, for an .idl file named **IIdlTestService.idl** and target output directory named **IIdlTestServiceTs**, the directory structure is similar to the following:
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
```
### Development Using TS
#### Creating an IDL File
You can use TS to create IDL files. An example IDL file is as follows:
```ts
interface OHOS.IIdlTestService {
int TestIntTransaction([in] int data);
void TestStringTransaction([in] String data);
}
├── IIdlTestServiceTs # IDL code output folder
│ ├── i_idl_test_service.ts # File generated
│ ├── idl_test_service_proxy.ts # File generated
│ ├── idl_test_service_stub.ts # File generated
│ └── IIdlTestService.idl # Constructed .idl file
└── idl.exe # Executable file of IDL
```
Run the **./idl -c IIdlTestService.idl -gen-ts -d /data/ts/** command (**-d** indicates the output directory) to generate the interface file, stub file, and proxy file in the **/data/ts** directory in the execution environment. The names of the generated interface class files are the same as that of the IDL file, except that the file name extension is **.ts**. For example, the files generated for the **IIdlTestService.idl** file are **i_idl_test_service.ts**, **idl_test_service_proxy.ts**, and **idl_test_service_stub.ts**.
#### Exposing Interfaces on the Server
The stub class generated by IDL is an abstract implementation of the interface class and declares all methods in the IDL file.
......@@ -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("onRemoteRequestEx 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;
}
```
## How to Develop for Interworking Between C++ and TS
### TS Proxy and C++ Stub Development
#### C++ Service Object
1. Use C++ to construct an IDL file and run commands to generate interfaces, stub files, and proxy files.
2. Create a service object, inherit the interface class defined in the C++ stub file, and implement the methods in the class. An example is as follows:
```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;
}
};
```
#### Native APIs in C++
C++ provides C++ service objects to TS in the format of native APIs. For example, C++ provides a **GetNativeObject** method, which is used to create an **IdlTestServiceImpl** instance. Using the **NAPI_ohos_rpc_CreateJsRemoteObject** method, you can create a JS remote object for the TS application.
```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 Object
Use TS to construct an IDL file and run commands to generate interfaces, stub files, and proxy files. An example proxy file is as follows:
```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
}
```
#### Interworking Between TS and C++ Applications
1. The TS application invokes the native API to obtain the remote C++ service object.
2. Construct a TS proxy and transfers the remote C++ service object to it.
3. Use the TS proxy to call the method declared in the IDL file to implement the interworking between the TS proxy and C++ stub. The following is an example:
```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);
// Call testIntTransaction.
tsProxy.testIntTransaction(10, testIntTransactionCallback);
// Call testStringTransaction.
tsProxy.testStringTransaction('test', testIntTransactionCallback);
}
```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册