1# Native Child Process Development (C/C++)
2
3You can create a child process in either of the following ways:
4- [Creating a Child Process That Supports IPC Callback](#creating-a-child-process-that-supports-ipc-callback): Create a child process and establish an IPC channel between the parent and child processes. This method applies to scenarios where the parent and child processes require IPC. Its usage depends on [IPC Kit](../ipc/ipc-capi-development-guideline.md).
5- [Creating a Child Process That Supports Pass-by-Parameter](#creating-a-child-process-that-supports-pass-by-parameter): Create a child process and pass the string and FD handle parameters to the child process. This method applies to scenarios where parameters need to be passed to child processes.
6
7
8## Creating a Child Process That Supports IPC Callback
9
10### When to Use
11
12This topic describes how to create a native child process in the main process and establish an IPC channel between the main process and child process. It makes multi-process programming at the native layer easier.
13
14### Available APIs
15
16| Name                                                                                                                                                                                                                                                                                                                               | Description                                                                                   |
17| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
18| int [OH_Ability_CreateNativeChildProcess](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_createnativechildprocess) (const char *libName, [OH_Ability_OnNativeChildProcessStarted](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_onnativechildprocessstarted) onProcessStarted) | Creates a child process, loads a specified dynamic link library, and returns the startup result asynchronously through a callback parameter. An independent thread is used to execute the callback function. When implementing the callback function, pay attention to thread synchronization issues and avoid performing time-consuming operations to prevent extended blocking.|
19
20> **NOTE**
21>
22> Currently, only 2-in-1 devices are supported, and only one native child process can be started for a process.
23
24### How to Develop
25
26This section describes how to use the C APIs provided by Ability Kit to create a native child process and establish an IPC channel between the main process and child process based on an existing native application development project.
27
28**Linking Dynamic Libraries**
29
30```txt
31libipc_capi.so
32libchild_process.so
33```
34
35**Including Header Files**
36
37```c++
38#include <IPCKit/ipc_kit.h>
39#include <AbilityKit/native_child_process.h>
40```
41
421. (Child process) Implement necessary export functions.
43
44    In the child process, implement and export the functions **NativeChildProcess_OnConnect** and **NativeChildProcess_MainProc**. (It is assumed that the code file is named **ChildProcessSample.cpp**.) The **OHIPCRemoteStub** object returned by **NativeChildProcess_OnConnect** is responsible for IPC of the main process. For details, see [IPC Development (C/C++)](../ipc/ipc-capi-development-guideline.md).
45
46    After the child process is started, **NativeChildProcess_OnConnect** is invoked to obtain an IPC stub object, and then **NativeChildProcess_MainProc** is called to transfer the control right of the main thread. After the second function is returned, the child process exits.
47
48    ```c++
49    #include <IPCKit/ipc_kit.h>
50
51    extern "C" {
52
53    OHIPCRemoteStub* NativeChildProcess_OnConnect()
54    {
55        // ipcRemoteStub points to the IPC stub object implemented by the child process. The object is used to receive and respond to IPC messages from the main process.
56        // The child process controls its lifecycle according to the service logic.
57        return ipcRemoteStub;
58    }
59
60    void NativeChildProcess_MainProc()
61    {
62        // Equivalent to the Main function of the child process. It implements the service logic of the child process.
63        // ...
64        // After the function is returned, the child process exits.
65    }
66
67    } // extern "C"
68    ```
69
702. (Child process) Compile a dynamic link library.
71
72    Modify the **CMakeList.txt** file, compile the file into a dynamic link library (named **libchildprocesssample.so** in this example), and add the dependency of the dynamic link library of IPC Kit.
73
74    ```txt
75    add_library(childprocesssample SHARED
76        # Source code file that implements the necessary export functions
77        ChildProcessSample.cpp
78
79        # Other source code files
80        # ...
81    )
82
83    target_link_libraries(childprocesssample PUBLIC
84        # Add the dependency of the dynamic link library of IPC Kit.
85        libipc_capi.so
86
87        # Dependencies of other dynamic link libraries
88        # ...
89    )
90    ```
91
923. (Main process) Implement the child process startup result callback.
93
94    ```c++
95    #include <IPCKit/ipc_kit.h>
96
97    static void OnNativeChildProcessStarted(int errCode, OHIPCRemoteProxy *remoteProxy)
98    {
99        if (errCode != NCP_NO_ERROR) {
100            // Exception handling when the child process is not started normally.
101            // ...
102            return;
103        }
104
105        // Save the remoteProxy object for IPC with the child process based on the APIs provided by IPC Kit.
106        // You are advised to transfer time-consuming operations to an independent thread to avoid blocking the callback thread for a long time.
107        // When the IPC object is no longer needed, call OH_IPCRemoteProxy_Destroy to release it.
108        // ...
109    }
110    ```
111
112    The second parameter **OHIPCRemoteProxy** in the callback function is used to establish an IPC channel with the **OHIPCRemoteStub** object returned by the **NativeChildProcess_OnConnect** method implemented by the child process. For details, see [IPC Development (C/C++)](../ipc/ipc-capi-development-guideline.md). When the **OHIPCRemoteProxy** object is no longer needed, call [OH_IPCRemoteProxy_Destroy](../reference/apis-ipc-kit/_o_h_i_p_c_remote_object.md#oh_ipcremoteproxy_destroy) to release it.
113
1144. (Main process) Start the native child process.
115
116    Call the API to start the native child process. Note that the return value **NCP_NO_ERROR** only indicates that the native child process startup logic is successfully called. The actual startup result is asynchronously notified through the callback function specified in the second parameter. **A child process can be created only in the main process.**
117
118    ```c++
119    #include <AbilityKit/native_child_process.h>
120
121    // The first parameter libchildprocesssample.so is the name of the dynamic link library that implements the necessary export functions of the child process.
122    int32_t ret = OH_Ability_CreateNativeChildProcess("libchildprocesssample.so", OnNativeChildProcessStarted);
123    if (ret != NCP_NO_ERROR) {
124        // Exception handling when the child process is not started normally.
125        // ...
126    }
127    ```
128
1295. (Main process) Add build dependencies.
130
131    Modify the **CMaklist.txt** file to add the dependencies. The following assumes that the main process is implemented in the library file named **libmainprocesssample.so**. (The implementation of the main process and child processes can be compiled to the same dynamic link library file.)
132
133    ```txt
134    target_link_libraries(mainprocesssample PUBLIC
135        # Add dependencies of the dynamic link library of IPC Kit and Ability Kit.
136        libipc_capi.so
137        libchild_process.so
138
139        # Dependencies of other dynamic link libraries
140        # ...
141    )
142    ```
143
144## Creating a Child Process That Supports Pass-by-Parameter
145
146### When to Use
147
148This section describes how to create a native child process and pass parameters to it.
149
150### Available APIs
151
152| Name                                                                                                                                                                                                                                                                                                                               | Description                                                                                   |
153| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
154| [Ability_NativeChildProcess_ErrCode](../reference/apis-ability-kit/c-apis-ability-childprocess.md#ability_nativechildprocess_errcode) [OH_Ability_StartNativeChildProcess](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_startnativechildprocess) (const char \*entry, [NativeChildProcess_Args](../reference/apis-ability-kit/c-apis-ability-childprocess.md#nativechildprocess_args) args, [NativeChildProcess_Options](../reference/apis-ability-kit/c-apis-ability-childprocess.md#nativechildprocess_options) options, int32_t *pid) | Starts a child process and returns its PID.|
155
156### How to Develop
157
158
159**Linking Dynamic Libraries**
160
161```txt
162libchild_process.so
163```
164
165**Including Header Files**
166
167```c++
168#include <AbilityKit/native_child_process.h>
169```
170
1711. (Child process) Implement necessary export functions.
172
173    In the child process, implement and export the entry function [NativeChildProcess_Args](../reference/apis-ability-kit/c-apis-ability-childprocess.md#nativechildprocess_args). (It is assumed that the code file is named **ChildProcessSample.cpp**.) After the child process is started, the entry function is invoked. After the second function is returned, the child process exits.
174
175    ```c++
176    #include <AbilityKit/native_child_process.h>
177
178    extern "C" {
179
180    /**
181     * Entry function of a child process, which implements the service logic of the child process.
182     * The function name can be customized and is specified when the main process calls the OH_Ability_StartNativeChildProcess method. In this example, the function name is Main.
183     * After the function is returned, the child process exits.
184     */
185    void Main(NativeChildProcess_Args args)
186    {
187        // Obtain the input entryPrams.
188        char *entryParams = args.entryParams;
189        // Obtain the input FD list.
190        NativeChildProcess_Fd *current = args.fdList.head;
191        while (current != nullptr) {
192            char *fdName = current->fdName;
193            int32_t fd = current->fd;
194            current = current->next;
195            // Service logic
196        }
197    }
198    } // extern "C"
199    ```
200
2012. (Child process) Compile a dynamic link library.
202
203    Modify the **CMakeList.txt** file, compile the file into a dynamic link library (named **libchildprocesssample.so** in this example), and add the dependency of the dynamic link library of Ability Kit.
204
205    ```txt
206    add_library(childprocesssample SHARED
207        # Source code file that implements the necessary export functions
208        ChildProcessSample.cpp
209
210        # Other source code files
211        # ...
212    )
213
214    target_link_libraries(childprocesssample PUBLIC
215        # Add the dependency of the dynamic link library of Ability Kit.
216        libchild_process.so
217
218        # Dependencies of other dynamic link libraries
219        # ...
220    )
221    ```
222
2233. (Main process) Start the native child process.
224
225    Call the API to start the native child process. The return value **NCP_NO_ERROR** indicates that the native child process is successfully started.
226
227    ```c++
228    #include <AbilityKit/native_child_process.h>
229    #include <stdlib.h>
230    #include <string.h>
231    #include <fcntl.h>
232
233    void startNativeChildProcess()
234    {
235        // ...
236        NativeChildProcess_Args args;
237        // Set entryParams. The maximum amount of data that can be passed is 150 KB.
238        args.entryParams = (char*)malloc(sizeof(char) * 10);
239        (void)strcpy(args.entryParams, "testParam");
240
241        // Insert a node to the head node of the linked list.
242        args.fdList.head = (NativeChildProcess_Fd*)malloc(sizeof(NativeChildProcess_Fd));
243        // FD keyword, which contains a maximum of 20 characters.
244        args.fdList.head->fdName = (char*)malloc(sizeof(char) * 4);
245        (void)strcpy(args.fdList.head->fdName, "fd1");
246        // Obtain the FD logic.
247        int32_t fd = open("/data/storage/el2/base/haps/entry/files/test.txt", O_RDWR | O_CREAT, 0644);
248        args.fdList.head->fd = fd;
249        // Insert only one FD record. You can insert a maximum of 16 FD records to the linked list as required.
250        args.fdList.head->next = NULL;
251        NativeChildProcess_Options options = {
252            .isolationMode = NCP_ISOLATION_MODE_ISOLATED
253        };
254
255        // The first parameter libchildprocesssample.so:Main indicates the name of the dynamic link library file that implements the Main method of the child process and the name of the entry method.
256        int32_t pid = -1;
257        Ability_NativeChildProcess_ErrCode ret = OH_Ability_StartNativeChildProcess(
258            "libchildprocesssample.so:Main", args, options, &pid);
259        if (ret != NCP_NO_ERROR) {
260            // Release the memory space in NativeChildProcess_Args to prevent memory leakage.
261            // Exception handling when the child process is not started normally.
262            // ...
263        }
264
265        // Other logic
266        // ...
267
268        // Release the memory space in NativeChildProcess_Args to prevent memory leakage.
269    }
270    ```
271
2724. (Main process) Add build dependencies.
273
274    Modify the **CMaklist.txt** file to add the dependencies. The following assumes that the main process is implemented in the library file named **libmainprocesssample.so**. (The implementation of the main process and child processes can be compiled to the same dynamic link library file.)
275
276    ```txt
277    target_link_libraries(mainprocesssample PUBLIC
278        # Add the dependency of the dynamic link library of Ability Kit.
279        libchild_process.so
280
281        # Dependencies of other dynamic link libraries
282        # ...
283    )
284    ```
285