harmony 鸿蒙Creating Native Child Processes (C/C++)

  • 2025-06-06
  • 浏览 (11)

Creating Native Child Processes (C/C++)

You can create a child process in either of the following ways: - 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. - 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.

Creating a Child Process That Supports IPC Callback

When to Use

This 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.

Available APIs

Name Description
int OH_Ability_CreateNativeChildProcess (const char *libName, 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.

NOTE

This function is valid only for 2-in-1 devices.

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.

How to Develop

This 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.

Linking Dynamic Libraries

libipc_capi.so
libchild_process.so

Including Header Files

#include <IPCKit/ipc_kit.h>
#include <AbilityKit/native_child_process.h>
  1. (Child process) Implement necessary export functions.

    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++).

    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.

    #include <IPCKit/ipc_kit.h>
    
    
    extern "C" {
    
    
    OHIPCRemoteStub* NativeChildProcess_OnConnect()
    {
        // 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.
        // The child process controls its lifecycle according to the service logic.
        return ipcRemoteStub;
    }
    
    
    void NativeChildProcess_MainProc()
    {
        // Equivalent to the Main function of the child process. It implements the service logic of the child process.
        // ...
        // After the function is returned, the child process exits.
    }
    
    
    } // extern "C"
    
  2. (Child process) Compile a dynamic link library.

    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.

    add_library(childprocesssample SHARED
        # Source code file that implements the necessary export functions
        ChildProcessSample.cpp
    
    
        # Other source code files
        # ...
    )
    
    
    target_link_libraries(childprocesssample PUBLIC
        # Add the dependency of the dynamic link library of IPC Kit.
        libipc_capi.so
    
    
        # Dependencies of other dynamic link libraries
        # ...
    )
    
  3. (Main process) Implement the child process startup result callback.

    #include <IPCKit/ipc_kit.h>
    
    
    static void OnNativeChildProcessStarted(int errCode, OHIPCRemoteProxy *remoteProxy)
    {
        if (errCode != NCP_NO_ERROR) {
            // Exception handling when the child process is not started normally.
            // ...
            return;
        }
    
    
        // Save the remoteProxy object for IPC with the child process based on the APIs provided by IPC Kit.
        // You are advised to transfer time-consuming operations to an independent thread to avoid blocking the callback thread for a long time.
        // When the IPC object is no longer needed, call OH_IPCRemoteProxy_Destroy to release it.
        // ...
    }
    

    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++). When the OHIPCRemoteProxy object is no longer needed, call OH_IPCRemoteProxy_Destroy to release it.

  4. (Main process) Start the native child process.

    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.

    #include <AbilityKit/native_child_process.h>
    
    
    // The first parameter libchildprocesssample.so is the name of the dynamic link library that implements the necessary export functions of the child process.
    int32_t ret = OH_Ability_CreateNativeChildProcess("libchildprocesssample.so", OnNativeChildProcessStarted);
    if (ret != NCP_NO_ERROR) {
        // Exception handling when the child process is not started normally.
        // ...
    }
    
  5. (Main process) Add build dependencies.

    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.)

    target_link_libraries(mainprocesssample PUBLIC
        # Add dependencies of the dynamic link library of IPC Kit and Ability Kit.
        libipc_capi.so
        libchild_process.so
    
    
        # Dependencies of other dynamic link libraries
        # ...
    )
    

Creating a Child Process That Supports Pass-by-Parameter

When to Use

This section describes how to create a native child process and pass parameters to it.

Available APIs

Name Description
Ability_NativeChildProcess_ErrCode OH_Ability_StartNativeChildProcess (const char *entry, NativeChildProcess_Args args, NativeChildProcess_Options options, int32_t *pid) Starts a child process and returns its PID.

How to Develop

Linking Dynamic Libraries

libchild_process.so

Including Header Files

#include <AbilityKit/native_child_process.h>
  1. (Child process) Implement necessary export functions.

    In the child process, implement and export the entry function 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.

    ”`c++ #include

    extern “C” {

    /**

    • Entry function of a child process, which implements the service logic of the child process.
    • 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.
    • After the function is returned, the child process exits. */ void Main(NativeChildProcess_Args args) { // Obtain the input entryPrams. char *entryParams = args.entryParams; // Obtain the input FD list. NativeChildProcess_Fd *current = args.fdList.head; while (current != nullptr) { char *fdName = current->fdName; int32_t fd = current->fd; current = current->next; // Service logic } } } // extern “C” “`
  2. (Child process) Compile a dynamic link library.

    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.

    add_library(childprocesssample SHARED
        # Source code file that implements the necessary export functions
        ChildProcessSample.cpp
    
    
        # Other source code files
        # ...
    )
    
    
    target_link_libraries(childprocesssample PUBLIC
        # Add the dependency of the dynamic link library of Ability Kit.
        libchild_process.so
    
    
        # Dependencies of other dynamic link libraries
        # ...
    )
    
  3. (Main process) Start the native child process.

    Call the API to start the native child process. The return value NCP_NO_ERROR indicates that the native child process is successfully started.

    #include <AbilityKit/native_child_process.h>
    #include <stdlib.h>
    #include <string.h>
    #include <fcntl.h>
    
    
    void startNativeChildProcess()
    {
        // ...
        NativeChildProcess_Args args;
        // Set entryParams. The maximum amount of data that can be passed is 150 KB.
        args.entryParams = (char*)malloc(sizeof(char) * 10);
        (void)strcpy(args.entryParams, "testParam");
    
    
        // Insert a node to the head node of the linked list.
        args.fdList.head = (NativeChildProcess_Fd*)malloc(sizeof(NativeChildProcess_Fd));
        // FD keyword, which contains a maximum of 20 characters.
        args.fdList.head->fdName = (char*)malloc(sizeof(char) * 4);
        (void)strcpy(args.fdList.head->fdName, "fd1");
        // Obtain the FD logic.
        int32_t fd = open("/data/storage/el2/base/haps/entry/files/test.txt", O_RDWR|O_CREAT, 0644);
        args.fdList.head->fd = fd;
        // Insert only one FD record. You can insert a maximum of 16 FD records to the linked list as required.
        args.fdList.head->next = NULL;
        NativeChildProcess_Options options = {
            .isolationMode = NCP_ISOLATION_MODE_ISOLATED
        };
    
    
        // 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.
        int32_t pid = -1;
        Ability_NativeChildProcess_ErrCode ret = OH_Ability_StartNativeChildProcess(
            "libchildprocesssample.so:Main", args, options, &pid);
        if (ret != NCP_NO_ERROR) {
            // Release the memory space in NativeChildProcess_Args to prevent memory leakage.
            // Exception handling when the child process is not started normally.
            // ...
        }
    
    
        // Other logic
        // ...
    
    
        // Release the memory space in NativeChildProcess_Args to prevent memory leakage.
    }
    
  4. (Main process) Add build dependencies.

    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.)

    target_link_libraries(mainprocesssample PUBLIC
        # Add the dependency of the dynamic link library of Ability Kit.
        libchild_process.so
    
    
        # Dependencies of other dynamic link libraries
        # ...
    )
    

Child Threads Obtaining Startup Parameters

When to Use

Since API version 17, child processes can obtain startup parameters.

Available APIs

Name Description
NativeChildProcess_Args* OH_Ability_GetCurrentChildProcessArgs() Returns the startup parameters of the child process.

How to Develop

Linking Dynamic Libraries

libchild_process.so

Including Header Files

#include <AbilityKit/native_child_process.h>

Obtaining Startup Parameters

After a child process is created through OH_Ability_StartNativeChildProcess, it can call OH_Ability_GetCurrentChildProcessArgs() to obtain the startup parameters NativeChildProcess_Args from any .so file or child thread, facilitating operations on related file descriptors.

#include <AbilityKit/native_child_process.h>
#include <thread>

extern "C" {

void ThreadFunc()
{
    // Obtain the startup parameters of the child process.
    NativeChildProcess_Args *args = OH_Ability_GetCurrentChildProcessArgs();
    // If the startup parameters fail to be obtained, a null pointer is returned.
    if (args == nullptr) {
        return;
    }
    // Obtain the value of entryPrams in the startup parameters.
    char *entryParams = args.entryParams;
    // Obtain the FD list.
    NativeChildProcess_Fd *current = args.fdList.head;
    while (current != nullptr) {
        char *fdName = current->fdName;
        int32_t fd = current->fd;
        current = current->next;
        // Service logic
    }
}

/**
 * Entry function of a child process, which implements the service logic of the child process.
 * args is the startup parameters of the child process.
 */
void Main(NativeChildProcess_Args args)
{
    // Service logic

    // Create a thread.
    std::thread tObj(ThreadFunc);
}

} // extern "C"

你可能感兴趣的鸿蒙文章

harmony 鸿蒙Ability Kit

harmony 鸿蒙Obtaining Reasons for Abnormal Application Exits

harmony 鸿蒙UIAbility Backup and Restore

harmony 鸿蒙Using Explicit Want to Start an Application Component

harmony 鸿蒙Introduction to Ability Kit

harmony 鸿蒙AbilityStage Component Container

harmony 鸿蒙Accessing a DataAbility

harmony 鸿蒙Accessing a DataShareExtensionAbility from the FA Model

harmony 鸿蒙Common action and entities Values (Not Recommended)

harmony 鸿蒙API Switching Overview

0  赞