DEV Community

Cover image for A Comprehensive Guide to Data Type Conversion Between ArkTS and C++ in HarmonyOS Next
kouwei qing
kouwei qing

Posted on

A Comprehensive Guide to Data Type Conversion Between ArkTS and C++ in HarmonyOS Next

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)  
{
}
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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();  
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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)