1# communication\_ipc<a name="EN-US_TOPIC_0000001103602398"></a>
2
3-   [Introduction](#section11660541593)
4-   [Architecture](#section1950291414611)
5-   [Directory Structure](#section161941989596)
6-   [Constraints](#section119744591305)
7-   [Compilation and Building](#section137768191623)
8-   [Usage](#section1312121216216)
9    -   [Available APIs](#section1551164914237)
10    -   [Usage Guidelines](#section129654513264)
11
12-   [Repositories Involved](#section1371113476307)
13
14## Introduction<a name="section11660541593"></a>
15
16The inter-process communication \(IPC\) and remote procedure call \(RPC\) mechanisms are used to implement cross-process communication. The difference between them lies in that IPC uses the Binder driver to implement cross-process communication within a device, whereas RPC uses the DSoftBus driver to implement cross-process communication across devices. IPC and RPC generally use a client-server model. The service requester \(client\) can obtain the proxy of the service provider \(server\) and use the proxy to read and write data, thus implementing data communication between processes. Generally, the server registers system abilities \(SAs\) with the system ability manager \(SAMgr\), which manages the SAs and provides APIs for the client. To communicate with a specific SA, the client must obtain the proxy of the SA from SAMgr. In this document, Proxy represents the service requester, and Stub represents the service provider.
17
18## Architecture<a name="section1950291414611"></a>
19
20**Figure  1**  IPC architecture<a name="fig312319321710"></a>
21![](figures/ipc-architecture.png "ipc-architecture")
22
23## Directory Structure<a name="section161941989596"></a>
24
25```
26/foundation/communication/ipc
27├── interfaces        # APIs exposed externally
28│   └── innerkits     # Header files for internal subsystems
29│       ├── ipc_core     # IPC APIs
30│       └── libdbinder   # dbinder APIs
31├── ipc            # IPC framework
32│   ├── native     # IPC native implementation
33│       ├── src    # IPC native source code
34│       └── test   # IPC native unit test cases
35│   └── test       # IPC native module test cases
36├── service        # dbinder implementation
37│   └── dbinder    # dbinder source code
38```
39
40## Constraints<a name="section119744591305"></a>
41
42Currently, cross-device RPC communication is not supported.
43
44## Compilation and Building<a name="section137768191623"></a>
45
46**Native Dependency**
47
48SDK dependency:
49
50```
51external_deps = [
52  "ipc:ipc_core",
53]
54```
55
56In addition, the refbase implementation on which IPC/RPC depends is stored in  **//utils**. Add the dependency on the Utils source code.
57
58```
59deps = [
60  "//utils/native/base:utils",
61]
62```
63
64## Usage<a name="section1312121216216"></a>
65
66The procedure for implementing cross-process communication using native APIs is similar to that using Java APIs.
67
681.  Define an interface.
69
70    The interface inherits  **IRemoteBroker**  and defines descriptors, functions, and message code.
71
722.  Implement the server provider \(stub\).
73
74    The stub inherits  **IRemoteStub\(Native\)**  or  **RemoteObject\(Java\)**  as well as  **AsObject**  and  **OnRemoteRequest**.
75
763.  Implement the service requester \(proxy\).
77
78    The proxy inherits  **IRemoteProxy\(Native\)**  or  **RemoteProxy\(Java\)**, encapsulates functions, and calls  **SendRequest**  to send requests to the stub.
79
804.  Register an SA.
81
82    After the process where the service provider resides starts, apply for the unique SA ID and register the stub with SAMgr.
83
845.  Obtain the SA.
856.  Obtain the proxy from the SAMgr based on the SA ID and device ID, and implement cross-process communication with the stub through the proxy.
86
87### Available APIs<a name="section1551164914237"></a>
88
89**Table  1**  Native IPC APIs
90
91<a name="table178849240013"></a>
92<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>Class/Interface</p>
93</th>
94<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>Method</p>
95</th>
96<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>Description</p>
97</th>
98</tr>
99</thead>
100<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>
101</td>
102<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&lt;IRemoteObject&gt; AsObject()</p>
103</td>
104<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>Obtains the holder of a remote proxy object. This method must be implemented by the derived classes of <strong id="b9012379013"><a name="b9012379013"></a><a name="b9012379013"></a>IRemoteBroker</strong>. If you call this method on the stub, the <strong id="b11613719015"><a name="b11613719015"></a><a name="b11613719015"></a>RemoteObject</strong> is returned; if you call this method on the proxy, the proxy object is returned.</p>
105</td>
106</tr>
107<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>
108</td>
109<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 &amp;data, MessageParcel &amp;reply, MessageOption &amp;option)</p>
110</td>
111<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p1188582414016"><a name="p1188582414016"></a><a name="p1188582414016"></a>Called to process a request from the proxy and return the result. Derived classes need to override this method.</p>
112</td>
113</tr>
114<tr id="row108856241904"><td class="cellrowborder" valign="top" width="14.12141214121412%" headers="mcps1.2.4.1.1 "><p id="p6885924609"><a name="p6885924609"></a><a name="p6885924609"></a>IRemoteProxy</p>
115</td>
116<td class="cellrowborder" valign="top" width="52.54525452545254%" headers="mcps1.2.4.1.2 ">&nbsp;&nbsp;</td>
117<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p688592413018"><a name="p688592413018"></a><a name="p688592413018"></a>Service proxy classes are derived from the <strong id="b8934204311212"><a name="b8934204311212"></a><a name="b8934204311212"></a>IRemoteProxy</strong> class.</p>
118</td>
119</tr>
120</tbody>
121</table>
122
123### Usage Guidelines<a name="section129654513264"></a>
124
125**Native**
126
127Define the IPC interface  **ITestAbility**.
128
129**ITestAbility**  inherits the IPC base class  **IRemoteBroker**  and defines descriptors, functions, and message code. The functions need to be implemented on both the proxy and stub.
130
131```
132class ITestAbility : public IRemoteBroker {
133public:
134// DECLARE_INTERFACE_DESCRIPTOR is mandatory, and the input parameter is std::u16string.
135DECLARE_INTERFACE_DESCRIPTOR(u"test.ITestAbility");
136int TRANS_ID_PING_ABILITY = 1; // Define the message code.
137virtual int TestPingAbility(const std::u16string &dummy) = 0; // Define functions.
138};
139```
140
141Define and implement service provider  **TestAbilityStub**.
142
143This class is related to the IPC framework and needs to inherit  **IRemoteStub<ITestAbility\>**. You need to override  **OnRemoteRequest**  on the stub to receive requests from the proxy.
144
145```
146class TestAbilityStub : public IRemoteStub<ITestAbility> {
147public:
148    virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
149    int TestPingAbility(const std::u16string &dummy) override;
150};
151
152int TestServiceStub::OnRemoteRequest(uint32_t code,
153    MessageParcel &data, MessageParcel &reply, MessageOption &option)
154{
155    switch (code) {
156        case TRANS_ID_PING_ABILITY: {
157            std::u16string dummy = data.ReadString16();
158            int result = TestPingAbility(dummy);
159            reply.WriteInt32(result);
160            return 0;
161        }
162        default:
163            return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
164    }
165}
166```
167
168Define the  **TestAbility**  class that implements functions for the stub.
169
170```
171class TestAbility : public TestAbilityStub {
172public:
173    int TestPingAbility(const std::u16string &dummy);
174}
175
176int TestAbility::TestPingAbility(const std::u16string &dummy) {
177    return 0;
178}
179```
180
181Define and implement  **TestAbilityProxy**.
182
183This class is implemented on the proxy and inherits  **IRemoteProxy<ITestAbility\>**. You can call  **SendRequest**  to send a request to the stub and expose the capabilities provided by the stub.
184
185```
186class TestAbilityProxy : public IRemoteProxy<ITestAbility> {
187public:
188    explicit TestAbilityProxy(const sptr<IRemoteObject> &impl);
189    int TestPingService(const std::u16string &dummy) override;
190private:
191    static inline BrokerDelegator<TestAbilityProxy> delegator_; // Use the iface_cast macro.
192}
193
194TestAbilityProxy::TestAbilityProxy(const sptr<IRemoteObject> &impl)
195    : IRemoteProxy<ITestAbility>(impl)
196{
197}
198
199int TestAbilityProxy::TestPingService(const std::u16string &dummy) {
200    MessageOption option;
201    MessageParcel dataParcel, replyParcel;
202    dataParcel.WriteString16(dummy);
203    int error = Remote()->SendRequest(TRANS_ID_PING_ABILITY, dataParcel, replyParcel, option);
204    int result = (error == ERR_NONE) ? replyParcel.ReadInt32() : -1;
205    return result;
206}
207```
208
209Send a request synchronously or asynchronously.
210
211The  **MessageOption**  parameter for the  **sendRequest\(\)**  method can be set to  **TF\_SYNC**,  **TF\_ASYNC**, using the  **MessageOption**  constructor or  **void SetFlags\(int flags\)**. The default value is  **TF\_SYNC**.
212
213```
214int SendRequest(uint32_t code, MessageParcel &data,
215    MessageParcel &reply, MessageOption &option) override;
216MessageOption option;
217option.setFlags(option.TF_ASYNC);
218```
219
220Register and start an SA.
221
222Call  **AddSystemAbility**  to register the  **TestAbilityStub**  instance of the SA with  **SystemAbilityManager**. The registration parameters vary depending on whether the  **SystemAbilityManager**  resides on the same device as the SA.
223
224```
225// Register the TestAbilityStub instance with the SystemAbilityManager on the same device as the SA.
226auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
227samgr->AddSystemAbility(said, new TestAbility());
228
229// Register the TestAbilityStub instance with the SystemAbilityManager on a different device.
230auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
231ISystemAbilityManager::SAExtraProp saExtra;
232saExtra.isDistributed = true; // Set a distributed SA.
233int result = samgr->AddSystemAbility(said, new TestAbility(), saExtra);
234```
235
236Obtain the SA.
237
238Call the  **GetSystemAbility**  function of the  **SystemAbilityManager**  class to obtain the  **IRemoteObject**  for the SA, and create a  **TestAbilityProxy**  instance.
239
240```
241// Obtain the proxy of the SA registered on the local device.
242sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
243sptr<IRemoteObject> remoteObject = samgr->GetSystemAbility(said);
244sptr<ITestAbility> testAbility = iface_cast<ITestAbility>(remoteObject); // Use the iface_cast macro to convert the proxy to a specific type.
245
246// Obtain the proxies of the SAs registered with other devices.
247sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
248sptr<IRemoteObject> remoteObject = samgr->GetSystemAbility(sdid, deviceId); // deviceId identifies a device.
249sptr<TestAbilityProxy> proxy(new TestAbilityProxy(remoteObject)); // Construct a proxy.
250```
251
252## Repositories Involved<a name="section1371113476307"></a>
253
254DSoftBus subsystem
255
256**communication\_ipc**
257
258[commonlibrary\_c\_utils](https://gitee.com/openharmony/commonlibrary_c_utils)
259
260[distributedschedule\_samgr](https://gitee.com/openharmony/distributedschedule_samgr)
261
262
263