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)