1e41f4b71Sopenharmony_ci# Native子进程开发指导(C/C++)
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci本模块提供了两种创建子进程的方式,开发者可根据需要进行选择。
4e41f4b71Sopenharmony_ci- [创建支持IPC回调的子进程](#创建支持ipc回调的子进程):创建子进程,并在父子进程间建立IPC通道,适用于父子进程需要IPC通信的场景。对[IPCKit](../ipc/ipc-capi-development-guideline.md)存在依赖。
5e41f4b71Sopenharmony_ci- [创建支持参数传递的子进程](#创建支持参数传递的子进程):创建子进程,并传递字符串和fd句柄参数到子进程。适用于需要传递参数到子进程的场景。
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ci
8e41f4b71Sopenharmony_ci## 创建支持IPC回调的子进程
9e41f4b71Sopenharmony_ci
10e41f4b71Sopenharmony_ci### 场景介绍
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ci本章节介绍如何在主进程中创建Native子进程,并在父子进程间建立IPC通道,方便开发者在Native层进行多进程编程。
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ci### 接口说明
15e41f4b71Sopenharmony_ci
16e41f4b71Sopenharmony_ci| 名称                                                                                                                                                                                                                                                                                                                                | 描述                                                                                    |
17e41f4b71Sopenharmony_ci| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
18e41f4b71Sopenharmony_ci| 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) | 创建子进程并加载参数中指定的动态链接库文件,进程启动结果通过回调参数异步通知,需注意回调通知为独立线程,回调函数实现需要注意线程同步,且不能执行高耗时操作避免长时间阻塞。 |
19e41f4b71Sopenharmony_ci
20e41f4b71Sopenharmony_ci> **说明:**
21e41f4b71Sopenharmony_ci>
22e41f4b71Sopenharmony_ci> 当前仅支持2in1设备,且单个进程只能启动一个Native子进程。
23e41f4b71Sopenharmony_ci
24e41f4b71Sopenharmony_ci### 开发步骤
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ci基于已创建完成的Native应用开发工程,在此基础上介绍如何使用`AbilityKit`提供的C API接口,创建Native子进程,并同时在父子进程间建立IPC通道。
27e41f4b71Sopenharmony_ci
28e41f4b71Sopenharmony_ci**动态库文件**
29e41f4b71Sopenharmony_ci
30e41f4b71Sopenharmony_ci```txt
31e41f4b71Sopenharmony_cilibipc_capi.so
32e41f4b71Sopenharmony_cilibchild_process.so
33e41f4b71Sopenharmony_ci```
34e41f4b71Sopenharmony_ci
35e41f4b71Sopenharmony_ci**头文件**
36e41f4b71Sopenharmony_ci
37e41f4b71Sopenharmony_ci```c++
38e41f4b71Sopenharmony_ci#include <IPCKit/ipc_kit.h>
39e41f4b71Sopenharmony_ci#include <AbilityKit/native_child_process.h>
40e41f4b71Sopenharmony_ci```
41e41f4b71Sopenharmony_ci
42e41f4b71Sopenharmony_ci1. 子进程-实现必要的导出方法。
43e41f4b71Sopenharmony_ci
44e41f4b71Sopenharmony_ci    在子进程中,实现必要的两个函数**NativeChildProcess_OnConnect**及**NativeChildProcess_MainProc**并导出(假设代码所在的文件名为ChildProcessSample.cpp)。其中NativeChildProcess_OnConnect方法返回的OHIPCRemoteStub对象负责主进程进行IPC通信,具体实现方法请参考[IPC通信开发指导(C/C++)](../ipc/ipc-capi-development-guideline.md),本文不再赘述。
45e41f4b71Sopenharmony_ci
46e41f4b71Sopenharmony_ci    子进程启动后会先调用NativeChildProcess_OnConnect获取IPC Stub对象,之后再调用NativeChildProcess_MainProc移交主线程控制权,该函数返回后子进程随即退出。
47e41f4b71Sopenharmony_ci
48e41f4b71Sopenharmony_ci    ```c++
49e41f4b71Sopenharmony_ci    #include <IPCKit/ipc_kit.h>
50e41f4b71Sopenharmony_ci
51e41f4b71Sopenharmony_ci    extern "C" {
52e41f4b71Sopenharmony_ci
53e41f4b71Sopenharmony_ci    OHIPCRemoteStub* NativeChildProcess_OnConnect()
54e41f4b71Sopenharmony_ci    {
55e41f4b71Sopenharmony_ci        // ipcRemoteStub指向子进程实现的ipc stub对象,用于接收来自主进程的IPC消息并响应
56e41f4b71Sopenharmony_ci        // 子进程根据业务逻辑控制其生命周期
57e41f4b71Sopenharmony_ci        return ipcRemoteStub;
58e41f4b71Sopenharmony_ci    }
59e41f4b71Sopenharmony_ci
60e41f4b71Sopenharmony_ci    void NativeChildProcess_MainProc()
61e41f4b71Sopenharmony_ci    {
62e41f4b71Sopenharmony_ci        // 相当于子进程的Main函数,实现子进程的业务逻辑
63e41f4b71Sopenharmony_ci        // ...
64e41f4b71Sopenharmony_ci        // 函数返回后子进程随即退出
65e41f4b71Sopenharmony_ci    }
66e41f4b71Sopenharmony_ci    
67e41f4b71Sopenharmony_ci    } // extern "C"
68e41f4b71Sopenharmony_ci    ```
69e41f4b71Sopenharmony_ci
70e41f4b71Sopenharmony_ci2. 子进程-编译为动态链接库。
71e41f4b71Sopenharmony_ci
72e41f4b71Sopenharmony_ci    修改CMakeList.txt文件,编译为动态链接库(假设需要编译出的库文件名称为libchildprocesssample.so),并添加IPC动态库依赖。
73e41f4b71Sopenharmony_ci
74e41f4b71Sopenharmony_ci    ```txt
75e41f4b71Sopenharmony_ci    add_library(childprocesssample SHARED
76e41f4b71Sopenharmony_ci        # 实现必要导出方法的源文件
77e41f4b71Sopenharmony_ci        ChildProcessSample.cpp
78e41f4b71Sopenharmony_ci        
79e41f4b71Sopenharmony_ci        # 其它代码源文件
80e41f4b71Sopenharmony_ci        # ...
81e41f4b71Sopenharmony_ci    )
82e41f4b71Sopenharmony_ci
83e41f4b71Sopenharmony_ci    target_link_libraries(childprocesssample PUBLIC
84e41f4b71Sopenharmony_ci        # 添加依赖的IPC动态库
85e41f4b71Sopenharmony_ci        libipc_capi.so
86e41f4b71Sopenharmony_ci        
87e41f4b71Sopenharmony_ci        # 其它所依赖的动态库
88e41f4b71Sopenharmony_ci        # ...
89e41f4b71Sopenharmony_ci    )
90e41f4b71Sopenharmony_ci    ```
91e41f4b71Sopenharmony_ci
92e41f4b71Sopenharmony_ci3. 主进程-实现子进程启动结果回调函数。
93e41f4b71Sopenharmony_ci
94e41f4b71Sopenharmony_ci    ```c++
95e41f4b71Sopenharmony_ci    #include <IPCKit/ipc_kit.h>
96e41f4b71Sopenharmony_ci
97e41f4b71Sopenharmony_ci    static void OnNativeChildProcessStarted(int errCode, OHIPCRemoteProxy *remoteProxy)
98e41f4b71Sopenharmony_ci    {
99e41f4b71Sopenharmony_ci        if (errCode != NCP_NO_ERROR) {
100e41f4b71Sopenharmony_ci            // 子进程未能正常启动时的异常处理
101e41f4b71Sopenharmony_ci            // ...
102e41f4b71Sopenharmony_ci            return;
103e41f4b71Sopenharmony_ci        }
104e41f4b71Sopenharmony_ci
105e41f4b71Sopenharmony_ci        // 保存remoteProxy对象,后续基于IPC Kit提供的API同子进程间进行IPC通信
106e41f4b71Sopenharmony_ci        // 耗时操作建议转移到独立线程去处理,避免长时间阻塞回调线程
107e41f4b71Sopenharmony_ci        // IPC对象使用完毕后,需要调用OH_IPCRemoteProxy_Destroy方法释放
108e41f4b71Sopenharmony_ci        // ...
109e41f4b71Sopenharmony_ci    }
110e41f4b71Sopenharmony_ci    ```
111e41f4b71Sopenharmony_ci
112e41f4b71Sopenharmony_ci    回调函数传递的第二个参数OHIPCRemoteProxy对象,会与子进程实现的**NativeChildProcess_OnConnect**方法返回的OHIPCRemoteStub对象间建立IPC通道,具体使用方法参考[IPC通信开发指导(C/C++)](../ipc/ipc-capi-development-guideline.md),本文不再赘述;OHIPCRemoteProxy对象使用完毕后,需要调用[OH_IPCRemoteProxy_Destory](../reference/apis-ipc-kit/_o_h_i_p_c_remote_object.md#oh_ipcremoteproxy_destroy)函数释放。
113e41f4b71Sopenharmony_ci
114e41f4b71Sopenharmony_ci4. 主进程-启动Native子进程。
115e41f4b71Sopenharmony_ci
116e41f4b71Sopenharmony_ci    调用API启动Native子进程,需要注意返回值为NCP_NO_ERROR仅代表成功调用native子进程启动逻辑,实际的启动结果通过第二个参数中指定的回调函数异步通知。需注意**仅允许在主进程中创建子进程**。
117e41f4b71Sopenharmony_ci
118e41f4b71Sopenharmony_ci    ```c++
119e41f4b71Sopenharmony_ci    #include <AbilityKit/native_child_process.h>
120e41f4b71Sopenharmony_ci
121e41f4b71Sopenharmony_ci    // 第一个参数"libchildprocesssample.so"为实现了子进程必要导出方法的动态库文件名称
122e41f4b71Sopenharmony_ci    int32_t ret = OH_Ability_CreateNativeChildProcess("libchildprocesssample.so", OnNativeChildProcessStarted);
123e41f4b71Sopenharmony_ci    if (ret != NCP_NO_ERROR) {
124e41f4b71Sopenharmony_ci        // 子进程未能正常启动时的异常处理
125e41f4b71Sopenharmony_ci        // ...
126e41f4b71Sopenharmony_ci    }
127e41f4b71Sopenharmony_ci    ```
128e41f4b71Sopenharmony_ci
129e41f4b71Sopenharmony_ci5. 主进程-添加编译依赖项。
130e41f4b71Sopenharmony_ci
131e41f4b71Sopenharmony_ci    修改CMaklist.txt添加必要的依赖库,假设主进程所在的so名称为libmainprocesssample.so(主进程和子进程的实现也可以选择编译到同一个动态库文件)。
132e41f4b71Sopenharmony_ci
133e41f4b71Sopenharmony_ci    ```txt
134e41f4b71Sopenharmony_ci    target_link_libraries(mainprocesssample PUBLIC
135e41f4b71Sopenharmony_ci        # 添加依赖的IPC及元能力动态库
136e41f4b71Sopenharmony_ci        libipc_capi.so
137e41f4b71Sopenharmony_ci        libchild_process.so
138e41f4b71Sopenharmony_ci        
139e41f4b71Sopenharmony_ci        # 其它依赖的动态库
140e41f4b71Sopenharmony_ci        # ...
141e41f4b71Sopenharmony_ci    )
142e41f4b71Sopenharmony_ci    ```
143e41f4b71Sopenharmony_ci
144e41f4b71Sopenharmony_ci## 创建支持参数传递的子进程
145e41f4b71Sopenharmony_ci
146e41f4b71Sopenharmony_ci### 场景介绍
147e41f4b71Sopenharmony_ci
148e41f4b71Sopenharmony_ci本章节介绍如何创建Native子进程,并传递参数到子进程。
149e41f4b71Sopenharmony_ci
150e41f4b71Sopenharmony_ci### 接口说明
151e41f4b71Sopenharmony_ci
152e41f4b71Sopenharmony_ci| 名称                                                                                                                                                                                                                                                                                                                                | 描述                                                                                    |
153e41f4b71Sopenharmony_ci| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
154e41f4b71Sopenharmony_ci| [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) | 启动子进程并返回子进程pid。 |
155e41f4b71Sopenharmony_ci
156e41f4b71Sopenharmony_ci### 开发步骤
157e41f4b71Sopenharmony_ci
158e41f4b71Sopenharmony_ci
159e41f4b71Sopenharmony_ci**动态库文件**
160e41f4b71Sopenharmony_ci
161e41f4b71Sopenharmony_ci```txt
162e41f4b71Sopenharmony_cilibchild_process.so
163e41f4b71Sopenharmony_ci```
164e41f4b71Sopenharmony_ci
165e41f4b71Sopenharmony_ci**头文件**
166e41f4b71Sopenharmony_ci
167e41f4b71Sopenharmony_ci```c++
168e41f4b71Sopenharmony_ci#include <AbilityKit/native_child_process.h>
169e41f4b71Sopenharmony_ci```
170e41f4b71Sopenharmony_ci
171e41f4b71Sopenharmony_ci1. 子进程-实现必要的导出方法。
172e41f4b71Sopenharmony_ci
173e41f4b71Sopenharmony_ci    在子进程中,实现参数为[NativeChildProcess_Args](../reference/apis-ability-kit/c-apis-ability-childprocess.md#nativechildprocess_args)入口函数并导出(假设代码所在的文件名为ChildProcessSample.cpp)。子进程启动后会调用该入口函数,该函数返回后子进程随即退出。
174e41f4b71Sopenharmony_ci
175e41f4b71Sopenharmony_ci    ```c++
176e41f4b71Sopenharmony_ci    #include <AbilityKit/native_child_process.h>
177e41f4b71Sopenharmony_ci
178e41f4b71Sopenharmony_ci    extern "C" {
179e41f4b71Sopenharmony_ci
180e41f4b71Sopenharmony_ci    /**
181e41f4b71Sopenharmony_ci     * 子进程的入口函数,实现子进程的业务逻辑
182e41f4b71Sopenharmony_ci     * 函数名称可以自定义,在主进程调用OH_Ability_StartNativeChildProcess方法时指定,此示例中为Main
183e41f4b71Sopenharmony_ci     * 函数返回后子进程退出
184e41f4b71Sopenharmony_ci     */
185e41f4b71Sopenharmony_ci    void Main(NativeChildProcess_Args args)
186e41f4b71Sopenharmony_ci    {
187e41f4b71Sopenharmony_ci        // 获取传入的entryPrams
188e41f4b71Sopenharmony_ci        char *entryParams = args.entryParams;
189e41f4b71Sopenharmony_ci        // 获取传入的fd列表
190e41f4b71Sopenharmony_ci        NativeChildProcess_Fd *current = args.fdList.head;
191e41f4b71Sopenharmony_ci        while (current != nullptr) {
192e41f4b71Sopenharmony_ci            char *fdName = current->fdName;
193e41f4b71Sopenharmony_ci            int32_t fd = current->fd;
194e41f4b71Sopenharmony_ci            current = current->next;
195e41f4b71Sopenharmony_ci            // 业务逻辑..
196e41f4b71Sopenharmony_ci        }
197e41f4b71Sopenharmony_ci    }
198e41f4b71Sopenharmony_ci    } // extern "C"
199e41f4b71Sopenharmony_ci    ```
200e41f4b71Sopenharmony_ci
201e41f4b71Sopenharmony_ci2. 子进程-编译为动态链接库。
202e41f4b71Sopenharmony_ci
203e41f4b71Sopenharmony_ci    修改CMakeList.txt文件,编译为动态链接库(假设需要编译出的库文件名称为libchildprocesssample.so),并添加元能力动态库依赖。
204e41f4b71Sopenharmony_ci
205e41f4b71Sopenharmony_ci    ```txt
206e41f4b71Sopenharmony_ci    add_library(childprocesssample SHARED
207e41f4b71Sopenharmony_ci        # 实现必要导出方法的源文件
208e41f4b71Sopenharmony_ci        ChildProcessSample.cpp
209e41f4b71Sopenharmony_ci        
210e41f4b71Sopenharmony_ci        # 其它代码源文件
211e41f4b71Sopenharmony_ci        # ...
212e41f4b71Sopenharmony_ci    )
213e41f4b71Sopenharmony_ci
214e41f4b71Sopenharmony_ci    target_link_libraries(childprocesssample PUBLIC
215e41f4b71Sopenharmony_ci        # 添加依赖的元能力动态库
216e41f4b71Sopenharmony_ci        libchild_process.so
217e41f4b71Sopenharmony_ci
218e41f4b71Sopenharmony_ci        # 其它所依赖的动态库
219e41f4b71Sopenharmony_ci        # ...
220e41f4b71Sopenharmony_ci    )
221e41f4b71Sopenharmony_ci    ```
222e41f4b71Sopenharmony_ci
223e41f4b71Sopenharmony_ci3. 主进程-启动Native子进程。
224e41f4b71Sopenharmony_ci
225e41f4b71Sopenharmony_ci    调用API启动Native子进程,返回值为NCP_NO_ERROR代表成功启动native子进程。
226e41f4b71Sopenharmony_ci
227e41f4b71Sopenharmony_ci    ```c++
228e41f4b71Sopenharmony_ci    #include <AbilityKit/native_child_process.h>
229e41f4b71Sopenharmony_ci    #include <stdlib.h>
230e41f4b71Sopenharmony_ci    #include <string.h>
231e41f4b71Sopenharmony_ci    #include <fcntl.h>
232e41f4b71Sopenharmony_ci
233e41f4b71Sopenharmony_ci    void startNativeChildProcess()
234e41f4b71Sopenharmony_ci    {
235e41f4b71Sopenharmony_ci        // ...
236e41f4b71Sopenharmony_ci        NativeChildProcess_Args args;
237e41f4b71Sopenharmony_ci        // 设置entryParams,支持传输的最大数据量为150KB
238e41f4b71Sopenharmony_ci        args.entryParams = (char*)malloc(sizeof(char) * 10);
239e41f4b71Sopenharmony_ci        (void)strcpy(args.entryParams, "testParam");
240e41f4b71Sopenharmony_ci
241e41f4b71Sopenharmony_ci        // 插入节点到链表头节点中
242e41f4b71Sopenharmony_ci        args.fdList.head = (NativeChildProcess_Fd*)malloc(sizeof(NativeChildProcess_Fd));
243e41f4b71Sopenharmony_ci        // fd关键字,最多不超过20个字符
244e41f4b71Sopenharmony_ci        args.fdList.head->fdName = (char*)malloc(sizeof(char) * 4);
245e41f4b71Sopenharmony_ci        (void)strcpy(args.fdList.head->fdName, "fd1");
246e41f4b71Sopenharmony_ci        // 获取fd逻辑
247e41f4b71Sopenharmony_ci        int32_t fd = open("/data/storage/el2/base/haps/entry/files/test.txt", O_RDWR | O_CREAT, 0644);
248e41f4b71Sopenharmony_ci        args.fdList.head->fd = fd;
249e41f4b71Sopenharmony_ci        // 此处只插入一个fd记录,根据需求可以插入更多fd记录到链表中,最多不超过16个
250e41f4b71Sopenharmony_ci        args.fdList.head->next = NULL;
251e41f4b71Sopenharmony_ci        NativeChildProcess_Options options = {
252e41f4b71Sopenharmony_ci            .isolationMode = NCP_ISOLATION_MODE_ISOLATED
253e41f4b71Sopenharmony_ci        };
254e41f4b71Sopenharmony_ci
255e41f4b71Sopenharmony_ci        // 第一个参数"libchildprocesssample.so:Main"为实现了子进程Main方法的动态库文件名称和入口方法名
256e41f4b71Sopenharmony_ci        int32_t pid = -1;
257e41f4b71Sopenharmony_ci        Ability_NativeChildProcess_ErrCode ret = OH_Ability_StartNativeChildProcess(
258e41f4b71Sopenharmony_ci            "libchildprocesssample.so:Main", args, options, &pid);
259e41f4b71Sopenharmony_ci        if (ret != NCP_NO_ERROR) {
260e41f4b71Sopenharmony_ci            // 释放NativeChildProcess_Args中的内存空间防止内存泄漏
261e41f4b71Sopenharmony_ci            // 子进程未能正常启动时的异常处理
262e41f4b71Sopenharmony_ci            // ...
263e41f4b71Sopenharmony_ci        }
264e41f4b71Sopenharmony_ci
265e41f4b71Sopenharmony_ci        // 其他逻辑
266e41f4b71Sopenharmony_ci        // ...
267e41f4b71Sopenharmony_ci
268e41f4b71Sopenharmony_ci        // 释放NativeChildProcess_Args中的内存空间防止内存泄漏
269e41f4b71Sopenharmony_ci    }
270e41f4b71Sopenharmony_ci    ```
271e41f4b71Sopenharmony_ci
272e41f4b71Sopenharmony_ci4. 主进程-添加编译依赖项。
273e41f4b71Sopenharmony_ci
274e41f4b71Sopenharmony_ci    修改CMaklist.txt添加必要的依赖库,假设主进程所在的so名称为libmainprocesssample.so(主进程和子进程的实现也可以选择编译到同一个动态库文件)。
275e41f4b71Sopenharmony_ci
276e41f4b71Sopenharmony_ci    ```txt
277e41f4b71Sopenharmony_ci    target_link_libraries(mainprocesssample PUBLIC
278e41f4b71Sopenharmony_ci        # 添加依赖的元能力动态库
279e41f4b71Sopenharmony_ci        libchild_process.so
280e41f4b71Sopenharmony_ci        
281e41f4b71Sopenharmony_ci        # 其它依赖的动态库
282e41f4b71Sopenharmony_ci        # ...
283e41f4b71Sopenharmony_ci    )
284e41f4b71Sopenharmony_ci    ```
285