The 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.
## Compilation and Building<a name="section137768191623"></a>
**Native Dependency**
SDK dependency:
```
external_deps = [
"ipc:ipc_core",
]
```
In addition, the refbase implementation on which IPC/RPC depends is stored in **//utils**. Add the dependency on the Utils source code.
```
deps = [
"//utils/native/base:utils",
]
```
## Usage<a name="section1312121216216"></a>
The procedure for implementing cross-process communication using native APIs is similar to that using Java APIs.
1. Define an interface.
The interface inherits **IRemoteBroker** and defines descriptors, functions, and message code.
2. Implement the server provider \(stub\).
The stub inherits **IRemoteStub\(Native\)** or **RemoteObject\(Java\)** as well as **AsObject** and **OnRemoteRequest**.
3. Implement the service requester \(proxy\).
The proxy inherits **IRemoteProxy\(Native\)** or **RemoteProxy\(Java\)**, encapsulates functions, and calls **SendRequest** to send requests to the stub.
4. Register an SA.
After the process where the service provider resides starts, apply for the unique SA ID and register the stub with SAMgr.
5. Obtain the SA.
6. 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.
### Available APIs<a name="section1551164914237"></a>
<tdclass="cellrowborder"valign="top"width="33.33333333333333%"headers="mcps1.2.4.1.3 "><pid="p13885724405"><aname="p13885724405"></a><aname="p13885724405"></a>Obtains the holder of a remote proxy object. This method must be implemented by the derived classes of <strongid="b9012379013"><aname="b9012379013"></a><aname="b9012379013"></a>IRemoteBroker</strong>. If you call this method on the stub, the <strongid="b11613719015"><aname="b11613719015"></a><aname="b11613719015"></a>RemoteObject</strong> is returned; if you call this method on the proxy, the proxy object is returned.</p>
<tdclass="cellrowborder"valign="top"width="33.33333333333333%"headers="mcps1.2.4.1.3 "><pid="p1188582414016"><aname="p1188582414016"></a><aname="p1188582414016"></a>Called to process a request from the proxy and return the result. Derived classes need to override this method.</p>
<tdclass="cellrowborder"valign="top"width="33.33333333333333%"headers="mcps1.2.4.1.3 "><pid="p688592413018"><aname="p688592413018"></a><aname="p688592413018"></a>Service proxy classes are derived from the <strongid="b8934204311212"><aname="b8934204311212"></a><aname="b8934204311212"></a>IRemoteProxy</strong> class.</p>
**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.
```
class ITestAbility : public IRemoteBroker {
public:
// DECLARE_INTERFACE_DESCRIPTOR is mandatory, and the input parameter is std::u16string.
int TRANS_ID_PING_ABILITY = 1; // Define the message code.
virtual int TestPingAbility(const std::u16string &dummy) = 0; // Define functions.
};
```
Define and implement service provider **TestAbilityStub**.
This 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.
```
class TestAbilityStub : public IRemoteStub<ITestAbility> {
Define the **TestAbility** class that implements functions for the stub.
```
class TestAbility : public TestAbilityStub {
public:
int TestPingAbility(const std::u16string &dummy);
}
int TestAbility::TestPingAbility(const std::u16string &dummy) {
return 0;
}
```
Define and implement **TestAbilityProxy**.
This 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.
```
class TestAbilityProxy : public IRemoteProxy<ITestAbility> {
The **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**.
Call **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.
```
// Register the TestAbilityStub instance with the SystemAbilityManager on the same device as the SA.
auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
samgr->AddSystemAbility(said, new TestAbility());
// Register the TestAbilityStub instance with the SystemAbilityManager on a different device.
auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
ISystemAbilityManager::SAExtraProp saExtra;
saExtra.isDistributed = true; // Set a distributed SA.
int result = samgr->AddSystemAbility(said, new TestAbility(), saExtra);
```
Obtain the SA.
Call the **GetSystemAbility** function of the **SystemAbilityManager** class to obtain the **IRemoteObject** for the SA, and create a **TestAbilityProxy** instance.
```
// Obtain the proxy of the SA registered on the local device.