Механизмы межпроцессного взаимодействия (IPC) и удаленного вызова процедур (RPC) используются для реализации межпроцессного взаимодействия. Разница между ними заключается в том, что IPC использует драйвер Binder для реализации межпроцессного взаимодействия внутри устройства, в то время как RPC использует драйвер DSoftBus для реализации межпроцессного взаимодействия между устройствами. IPC и RPC обычно используют модель клиент-сервер. Запросчик услуги (клиент) может получить прокси-объект поставщика услуги (сервера) и использовать прокси-объект для чтения и записи данных, тем самым реализуя межпроцессное взаимодействие данных. Обычно сервер регистрирует системные возможности (SAs) с управляющим модулем системных возможностей (SAMgr), который управляет SAs и предоставляет API для клиента. Чтобы связаться с определенной SA, клиент должен получить прокси-объект SA из SAMgr. В этом документе Proxy представляет запросчика услуги, а Stub представляет поставщика услуги.## Архитектура
/foundation/communication/ipc
├── interfaces # Внешние API
│ └── innerkits # Заголовочные файлы для внутренних подсистем
│ ├── ipc_core # API IPC
│ └── libdbinder # API dbinder
├── ipc # Фреймворк IPC
│ ├── native # Нативная реализация IPC
│ ├── src # Исходный код IPC
│ └── test # Нативные тестовые случаи IPC
│ └── test # Тестовые случаи модуля IPC
├── service # Реализация dbinder
│ └── dbinder # Исходный код dbinder
В настоящее время поддержка RPC-коммуникации между разными устройствами не реализована.
Нативная зависимость
Зависимость SDK:
external_deps = [
"ipc:ipc_core",
]
Кроме того, реализация refbase, на которой зависит IPC/RPC, хранится в //utils. Добавьте зависимость на исходный код Utils.
deps = [
"//utils/native/base:utils",
]
Процедура реализации межпроцессного взаимодействия с помощью нативных API аналогична процедуре использования Java API.
Определите интерфейс.
Интерфейс наследуется от IRemoteBroker и определяет дескрипторы, функции и код сообщений.
Реализуйте серверный провайдер (stub).
Stub наследуется от IRemoteStub(Native) или RemoteObject(Java), а также от AsObject и OnRemoteRequest.3. Реализуйте запросчика услуги (proxy).
Proxy наследуется от IRemoteProxy(Native) или RemoteProxy(Java), упаковывает функции и вызывает SendRequest для отправки запросов stub.
Зарегистрируйте SA.
После запуска процесса, в котором находится провайдер услуги, подайте заявку на уникальный идентификатор SA и зарегистрируйте stub с SAMgr.
Получите SA.
Получите proxy из SAMgr на основе идентификатора SA и идентификатора устройства, и реализуйте межпроцессное взаимодействие через proxy.
Таблица 1 Нативные API IPC``` Таблица 1
<table>
<thead align="left">
<tr id="row6884924608">
<th class="cellrowborder" valign="top" width="14. 12141214121412%" id="mcps1. 2. 4. 1. 1">
<p id="p98846241706"><a name="p98846241706"></a><a name="p98846241706"></a>Класс/Интерфейс</p>
</th>
<th class="cellrowborder" valign="top" width="52. 54525452545254%" id="mcps1. 2. 4. 1. 2">
<p id="p1488482414020"><a name="p1488482414020"></a><a name="p1488482414020"></a>Метод</p>
</th>
<th class="cellrowborder" valign="top" width="33. 33333333333333%" id="mcps1. 2. 4. 1. 3">
<p id="p388516244016"><a name="p388516244016"></a><a name="p388516244016"></a>Описание</p>
</th>
</tr>
</thead>
<tbody>
<tr id="row15885824402">
<td class="cellrowborder" valign="top" width="14. 12141214121412%" headers="mcps1. 2. 4. 1. 1">
<p id="p08859241008"><a name="p08859241008"></a><a name="p08859241008"></a>IRemoteBroker</p>
</td>
<td class="cellrowborder" valign="top" width="52. 54525452545254%" headers="mcps1. 2. 4. 1. 2">
<p id="p388572412010"><a name="p388572412010"></a><a name="p388572412010"></a>sptr<IRemoteObject> AsObject()</p>
</td>
<td class="cellrowborder" valign="top" width="33. 33333333333333%" headers="mcps1. 2. 4. 1. 3">
<p id="p13885724405"><a name="p13885724405"></a><a name="p13885724405"></a>Получает держателя удаленного прокси-объекта. Этот метод должен быть реализован производными классами <strong id="b9012379013"><a name="b9012379013"></a><a name="b9012379013"></a>IRemoteBroker</strong>. Если этот метод вызывается на stub, возвращается <strong id="b11613719015"><a name="b11613719015"></a><a name="b11613719015"></a>RemoteObject</strong>; если этот метод вызывается на прокси, возвращается прокси-объект. </p>
</td>
</tr>
<tr id="row138859241808">
<td class="cellrowborder" valign="top" width="14. 12141214121412%" headers="mcps1. 2. 4. 1. 1">
<p id="p1888515245012"><a name="p1888515245012"></a><a name="p1888515245012"></a>IRemoteStub</p>
</td>
<td class="cellrowborder" valign="top" width="52. 54525452545254%" headers="mcps1. 2. 4. 1. 2">
```<p id="p1388516240011"><a name="p1388516240011"></a><a name="p1388516240011"></a>virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3">
<p id="p1388517244012"><a name="p1388517244012"></a><a name="p1388517244012"></a>Виртуальный метод, вызываемый для обработки удаленных запросов. Этот метод должен быть реализован производными классами <strong id="b11613719015"><a name="b11613719015"></a><a name="b11613719015"></a>IRemoteStub</strong>. Он принимает код запроса, данные запроса, данные ответа и опции запроса.</p>
</td>
</tr>
</tbody>
</table>```markdown
<tr id="row1188582414016">
<td class="cellrowborder" valign="top" width="14.12141214121412%" headers="mcps1.2.4.1.1">
<p id="p1188582414016"><a name="p1188582414016"></a><a name="p1188582414016"></a>Вызывается для обработки запроса от прокси и возврата результата. Производные классы должны переопределить этот метод.</p>
</td>
<td class="cellrowborder" valign="top" width="52.54525452545254%" headers="mcps1.2.4.1.2">
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3">
<p id="p1188582413018"><a name="p1188582413018"></a><a name="p1188582413018"></a>Классы-прокси для сервисов наследуются от класса <strong id="b11885824311212"><a name="b11885824311212"></a><a name="b11885824311212"></a>IRemoteProxy</strong>.</p>
</td>
</tr>
```### Правила использования<a name="section129654513264"></a>**Исходный код**
Определите интерфейс IPC **ITestAbility**.
**ITestAbility** наследует базовый класс IPC **IRemoteBroker** и определяет дескрипторы, функции и код сообщений. Функции должны быть реализованы как на стороне прокси, так и на стороне stub.
```cpp
class ITestAbility : public IRemoteBroker {
public:
// DECLARE_INTERFACE_DESCRIPTOR является обязательным, и входной параметр — это std::u16string.
DECLARE_INTERFACE_DESCRIPTOR(u"test.ITestAbility");
int TRANS_ID_PING_ABILITY = 1; // Определите код сообщения.
virtual int TestPingAbility(const std::u16string &dummy) = 0; // Определите функции.
};
Определите и реализуйте поставщика услуг TestAbilityStub.
Этот класс связан с фреймворком IPC и должен наследовать IRemoteStub. Вам нужно переопределить OnRemoteRequest на стороне stub для получения запросов от прокси.
class TestAbilityStub : public IRemoteStub<ITestAbility> {
public:
virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
int TestPingAbility(const std::u16string &dummy) override;
};
int TestAbilityStub::OnRemoteRequest(uint32_t code,
MessageParcel &data, MessageParcel &reply, MessageOption &option)
{
switch (code) {
case TRANS_ID_PING_ABILITY: {
std::u16string dummy = data.ReadString16();
int result = TestPingAbility(dummy);
reply.WriteInt32(result);
return 0;
}
default:
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
}
Определите класс TestAbility, который реализует функции для stub.
class TestAbility : public TestAbilityStub {
public:
int TestPingAbility(const std::u16string &dummy);
}
int TestAbility::TestPingAbility(const std::u16string &dummy) {
return 0;
}
```Определите и реализуйте **TestAbilityProxy**.
Этот класс реализуется на стороне прокси и наследует **IRemoteProxy<ITestAbility>**. Вы можете использовать метод **SendRequest** для отправки запроса на stub и предоставления возможностей, предоставляемых stub.
```cpp
class TestAbilityProxy : public IRemoteProxy<ITestAbility> {
public:
explicit TestAbilityProxy(const sptr<IRemoteObject> &impl);
int TestPingService(const std::u16string &dummy) override;
private:
static inline BrokerDelegator<TestAbilityProxy> delegator_; // Используйте макрос iface_cast.
}
TestAbilityProxy::TestAbilityProxy(const sptr<IRemoteObject> &impl)
: IRemoteProxy<ITestAbility>(impl)
{
}
int TestAbilityProxy::TestPingService(const std::u16string &dummy) {
MessageOption option;
MessageParcel dataParcel, replyParcel;
dataParcel.WriteString16(dummy);
int error = Remote()->SendRequest(TRANS_ID_PING_ABILITY, dataParcel, replyParcel, option);
int result = (error == ERR_NONE) ? replyParcel.ReadInt32() : -1;
return result;
}
Отправка запроса синхронно или асинхронно.
Параметр MessageOption для метода SendRequest() можно установить в TF_SYNC, TF_ASYNC, используя конструктор MessageOption или метод void SetFlags(int flags). Значение по умолчанию — TF_SYNC.
int SendRequest(uint32_t code, MessageParcel &data,
MessageParcel &reply, MessageOption &option) override;
MessageOption option;
option.setFlags(option.TF_ASYNC);
Регистрация и запуск SA.
Вызов AddSystemAbility для регистрации экземпляра SA TestAbilityStub с SystemAbilityManager. Параметры регистрации зависят от того, находится ли SystemAbilityManager на том же устройстве, что и SA.
// Регистрация экземпляра TestAbilityStub с SystemAbilityManager на том же устройстве, что и SA.
auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
samgr->AddSystemAbility(said, new TestAbility());
```// Регистрация экземпляра TestAbilityStub с SystemAbilityManager на другом устройстве.
auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
ISystemAbilityManager::SAExtraProp saExtra;
saExtra.isDistributed = true; // Установка распределенного SA.
int result = samgr->AddSystemAbility(said, new TestAbility(), saExtra);
Получение SA.
Вызов функции GetSystemAbility класса SystemAbilityManager для получения IRemoteObject для SA и создания экземпляра TestAbilityProxy.
// Получение прокси SA, зарегистрированного на локальном устройстве.
sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
sptr<IRemoteObject> remoteObject = samgr->GetSystemAbility(said);
sptr<ITestAbility> testAbility = iface_cast<ITestAbility>(remoteObject); // Использование макроса iface_cast для преобразования прокси в определенный тип.
```// Получить прокси SAs, зарегистрированные с другими устройствями.
sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
sptr<IRemoteObject> remoteObject = samgr->GetSystemAbility(sdid, deviceId); // deviceId идентифицирует устройство.
sptr<TestAbilityProxy> proxy(new TestAbilityProxy(remoteObject)); // Создать прокси.
## Вовлечённые репозитории<a name="section1371113476307"></a>
DSoftBus подсистема
**communication_ipc**
[commonlibrary_c_utils](https://gitee.com/openharmony/commonlibrary_c_utils)
[distributedschedule_samgr](https://gitee.com/openharmony/distributedschedule_samgr)
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )