A Comprehensive Guide to Data Type Conversion Between ArkTS and C++ in HarmonyOS Next
Background
ArkTS is the primary development language for HarmonyOS, with C++ support provided for certain capabilities—such as audio-video codecs—where HarmonyOS only offers C++ APIs. For migrating existing capabilities from other platforms, C++ is also the most efficient choice. Thus, mastering interaction between ArkTS and C++ has become an essential skill for HarmonyOS developers.
Each programming language defines its own data types, and cross-language function calls involve type conversion. ArkTS-C++ conversion is primarily provided by Node-API interfaces. This article introduces the conversion interfaces and best practices.
Developers familiar with Android JNI (Java Native Interface) know that JNI provides type conversion between Java and C++. Unlike JNI, NAPI (Node-API) encapsulates all parameters for TS-to-C++ calls into a single structure:
static napi_value add(napi_env env, napi_callback_info info)  
{
}
Regardless of the parameter count, all arguments are encapsulated in napi_callback_info, which can be parsed as:
size_t argc = 7; // Number of parameters
napi_value args[7] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
Parameters passed from ArkTS can then be read from the args array. The following sections detail type conversion methods.  
Converting ArkTS Types to C++
Basic Data Types
ArkTS basic types:
- Number (numeric)
- String
- Boolean
- BigInt (arbitrary-precision integer)
- Object
C++ basic types:
- Integer: int,short,long,long long
- Floating-point: float,double,long double
- Character: char
- Boolean: bool
NAPI conversion functions for basic types:
- To boolean: napi_get_value_bool
- To int32: napi_get_value_int32
- To int64: napi_get_value_int64
- To uint32: napi_get_value_uint32
- To double: napi_get_value_double
- To bigint (signed 64-bit): napi_get_value_bigint_int64
- To bigint (unsigned 64-bit): napi_get_value_bigint_uint64
Except for bool, TS numeric types map to various C++ numeric subtypes, each requiring a specific conversion function:
int intValue;
napi_get_value_int32(env, args[0], &intValue);
String Conversion
String and object handling is more complex. Use napi_get_value_string_utf8 to convert a JS string to a C++ std::string. First, determine the string length:
napi_status napi_get_value_string_utf8(napi_env env,
                                       napi_value value,
                                       char* buf,
                                       size_t bufsize,
                                       size_t* result)
The following utility function converts a JS string to a C++ string:
void JsValueToString(const napi_env &env, const napi_value &value, std::string &target) {  
    size_t result = 0;  
    napi_get_value_string_utf8(env, value, nullptr, 0, &result);  
    std::unique_ptr<char[]> buf(new char[result+1]);  
    if (!buf.get()) {  
        return;  
    }  
    memset(buf.get(), 0, result+1);  
    napi_get_value_string_utf8(env, value, buf.get(), result+1, &result);  
    target = buf.get();  
}
Object Conversion
To parse object parameters, convert them to napi_value via napi_get_cb_info, then use napi_get_named_property to retrieve attributes:
// ArkTS object:
export class Task {  
  public id: number; // Unique task identifier  
  public channel?: number;   
  //...
}
napi_value Demo::startTask(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value js_obj;
    napi_get_cb_info(env, info, &argc, &js_obj, nullptr, nullptr);
    napi_value taskIdNapiValue;
    napi_get_named_property(env, js_obj, "id", &taskIdNapiValue);
    int32_t taskid;
    napi_get_value_int32(env, taskIdNapiValue, &taskid);
    napi_value channelSelectNapiValue;
    napi_get_named_property(env, js_obj, "channelSelect", &channelSelectNapiValue);
    int32_t channel_select;
    napi_get_value_int32(env, channelSelectNapiValue, &channel_select);
    // ... Business logic
    return nullptr;
}
Array Conversion
Similar to strings, arrays require length retrieval via napi_get_array_length before element extraction with napi_get_element:
napi_value Demo::setArrays(napi_env env, napi_callback_info info) {
    std::vector<std::string> backupip_list;
    size_t argc = 1;
    napi_value args[1] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    bool is_array;
    napi_is_array(env, args[0], &is_array);
    if (!is_array) {
        return nullptr;
    }
    napi_value array = args[0];
    uint32_t length;
    napi_get_array_length(env, array, &length);
    for (int i = 0; i < length; i++) {
        napi_value element;
        napi_get_element(env, array, i, &element);
        std::string ipStr;
        NapiUtil::JsValueToString(env, element, ipStr);
        backupip_list.push_back(ipStr);
    }   
    // ... Business logic
    return nullptr;
}
ArrayBuffer Conversion
For binary data transfer from TS to C++, use napi_get_arraybuffer_info to convert ArrayBuffer to a C++ byte stream:
napi_status napi_get_arraybuffer_info(napi_env env,
                                      napi_value arraybuffer,
                                      void** data,
                                      size_t* byte_length)
Example usage:
napi_value Demo::setArrayBufferData(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value js_cb;
    napi_get_cb_info(env, info, &argc, &js_cb, nullptr, nullptr);
    void* buffer; 
    size_t length; 
    napi_get_arraybuffer_info(env, js_cb, &buffer, &length); 
    uint32_t* data = (uint32_t*) buffer;
    // ... Business logic
    return nullptr;
}
Converting C++ Types to ArkTS
To return specific types from C++ to TS (instead of nullptr), convert C++ types to TS via NAPI functions that create napi_value objects:  
- 
napi_create_uint32
- 
napi_create_int64
- 
napi_create_double
- 
napi_create_bigint_int64
- 
napi_create_bigint_uint64
- 
napi_create_bigint_words
- 
napi_create_string_utf8(and others for different encodings)
Example:
napi_value Demo::hasSon(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    int id;
    napi_get_value_int32(env, args[0], &id);
    napi_value result;
    bool hasSonById = _HasSon(id);
    napi_get_boolean(env, hasSonById, &result);
    return result;
}
Summary
This article introduces data types in C++ and TS, along with bidirectional conversion methods. Mastering these conversions enables efficient interaction with C++ modules in HarmonyOS development.
 
 
              
 
    
Top comments (0)