• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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> This function is valid only for 2-in-1 devices.
23>
24> Since API version 15, a single process supports a maximum of 50 native child processes. In API version 14 and earlier versions, a single process supports only one native child process.
25
26### How to Develop
27
28This 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.
29
30**Linking Dynamic Libraries**
31
32```txt
33libipc_capi.so
34libchild_process.so
35```
36
37**Including Header Files**
38
39```c++
40#include <IPCKit/ipc_kit.h>
41#include <AbilityKit/native_child_process.h>
42```
43
441. (Child process) Implement necessary export functions.
45
46    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).
47
48    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.
49
50    ```c++
51    #include <IPCKit/ipc_kit.h>
52
53    extern "C" {
54
55    OHIPCRemoteStub* NativeChildProcess_OnConnect()
56    {
57        // 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.
58        // The child process controls its lifecycle according to the service logic.
59        return ipcRemoteStub;
60    }
61
62    void NativeChildProcess_MainProc()
63    {
64        // Equivalent to the Main function of the child process. It implements the service logic of the child process.
65        // ...
66        // After the function is returned, the child process exits.
67    }
68
69    } // extern "C"
70    ```
71
722. (Child process) Compile a dynamic link library.
73
74    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.
75
76    ```txt
77    add_library(childprocesssample SHARED
78        # Source code file that implements the necessary export functions
79        ChildProcessSample.cpp
80
81        # Other source code files
82        # ...
83    )
84
85    target_link_libraries(childprocesssample PUBLIC
86        # Add the dependency of the dynamic link library of IPC Kit.
87        libipc_capi.so
88
89        # Dependencies of other dynamic link libraries
90        # ...
91    )
92    ```
93
943. (Main process) Implement the child process startup result callback.
95
96    ```c++
97    #include <IPCKit/ipc_kit.h>
98
99    static void OnNativeChildProcessStarted(int errCode, OHIPCRemoteProxy *remoteProxy)
100    {
101        if (errCode != NCP_NO_ERROR) {
102            // Exception handling when the child process is not started normally.
103            // ...
104            return;
105        }
106
107        // Save the remoteProxy object for IPC with the child process based on the APIs provided by IPC Kit.
108        // You are advised to transfer time-consuming operations to an independent thread to avoid blocking the callback thread for a long time.
109        // When the IPC object is no longer needed, call OH_IPCRemoteProxy_Destroy to release it.
110        // ...
111    }
112    ```
113
114    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.
115
1164. (Main process) Start the native child process.
117
118    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.**
119
120    ```c++
121    #include <AbilityKit/native_child_process.h>
122
123    // The first parameter libchildprocesssample.so is the name of the dynamic link library that implements the necessary export functions of the child process.
124    int32_t ret = OH_Ability_CreateNativeChildProcess("libchildprocesssample.so", OnNativeChildProcessStarted);
125    if (ret != NCP_NO_ERROR) {
126        // Exception handling when the child process is not started normally.
127        // ...
128    }
129    ```
130
1315. (Main process) Add build dependencies.
132
133    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.)
134
135    ```txt
136    target_link_libraries(mainprocesssample PUBLIC
137        # Add dependencies of the dynamic link library of IPC Kit and Ability Kit.
138        libipc_capi.so
139        libchild_process.so
140
141        # Dependencies of other dynamic link libraries
142        # ...
143    )
144    ```
145
146## Creating a Child Process That Supports Pass-by-Parameter
147
148### When to Use
149
150This section describes how to create a native child process and pass parameters to it.
151
152### Available APIs
153
154| Name                                                                                                                                                                                                                                                                                                                               | Description                                                                                   |
155| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
156| [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.|
157
158### How to Develop
159
160
161**Linking Dynamic Libraries**
162
163```txt
164libchild_process.so
165```
166
167**Including Header Files**
168
169```c++
170#include <AbilityKit/native_child_process.h>
171```
172
1731. (Child process) Implement necessary export functions.
174
175    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.
176
177    ```c++
178    #include <AbilityKit/native_child_process.h>
179
180    extern "C" {
181
182    /**
183     * Entry function of a child process, which implements the service logic of the child process.
184     * 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.
185     * After the function is returned, the child process exits.
186     */
187    void Main(NativeChildProcess_Args args)
188    {
189        // Obtain the input entryPrams.
190        char *entryParams = args.entryParams;
191        // Obtain the input FD list.
192        NativeChildProcess_Fd *current = args.fdList.head;
193        while (current != nullptr) {
194            char *fdName = current->fdName;
195            int32_t fd = current->fd;
196            current = current->next;
197            // Service logic
198        }
199    }
200    } // extern "C"
201    ```
202
2032. (Child process) Compile a dynamic link library.
204
205    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.
206
207    ```txt
208    add_library(childprocesssample SHARED
209        # Source code file that implements the necessary export functions
210        ChildProcessSample.cpp
211
212        # Other source code files
213        # ...
214    )
215
216    target_link_libraries(childprocesssample PUBLIC
217        # Add the dependency of the dynamic link library of Ability Kit.
218        libchild_process.so
219
220        # Dependencies of other dynamic link libraries
221        # ...
222    )
223    ```
224
2253. (Main process) Start the native child process.
226
227    Call the API to start the native child process. The return value **NCP_NO_ERROR** indicates that the native child process is successfully started.
228
229    ```c++
230    #include <AbilityKit/native_child_process.h>
231    #include <stdlib.h>
232    #include <string.h>
233    #include <fcntl.h>
234
235    void startNativeChildProcess()
236    {
237        // ...
238        NativeChildProcess_Args args;
239        // Set entryParams. The maximum amount of data that can be passed is 150 KB.
240        args.entryParams = (char*)malloc(sizeof(char) * 10);
241        (void)strcpy(args.entryParams, "testParam");
242
243        // Insert a node to the head node of the linked list.
244        args.fdList.head = (NativeChildProcess_Fd*)malloc(sizeof(NativeChildProcess_Fd));
245        // FD keyword, which contains a maximum of 20 characters.
246        args.fdList.head->fdName = (char*)malloc(sizeof(char) * 4);
247        (void)strcpy(args.fdList.head->fdName, "fd1");
248        // Obtain the FD logic.
249        int32_t fd = open("/data/storage/el2/base/haps/entry/files/test.txt", O_RDWR | O_CREAT, 0644);
250        args.fdList.head->fd = fd;
251        // Insert only one FD record. You can insert a maximum of 16 FD records to the linked list as required.
252        args.fdList.head->next = NULL;
253        NativeChildProcess_Options options = {
254            .isolationMode = NCP_ISOLATION_MODE_ISOLATED
255        };
256
257        // 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.
258        int32_t pid = -1;
259        Ability_NativeChildProcess_ErrCode ret = OH_Ability_StartNativeChildProcess(
260            "libchildprocesssample.so:Main", args, options, &pid);
261        if (ret != NCP_NO_ERROR) {
262            // Release the memory space in NativeChildProcess_Args to prevent memory leakage.
263            // Exception handling when the child process is not started normally.
264            // ...
265        }
266
267        // Other logic
268        // ...
269
270        // Release the memory space in NativeChildProcess_Args to prevent memory leakage.
271    }
272    ```
273
2744. (Main process) Add build dependencies.
275
276    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.)
277
278    ```txt
279    target_link_libraries(mainprocesssample PUBLIC
280        # Add the dependency of the dynamic link library of Ability Kit.
281        libchild_process.so
282
283        # Dependencies of other dynamic link libraries
284        # ...
285    )
286    ```
287