ArkRuntime 与类 Node.js 运行时差异
ArkRuntime(方舟运行时) 为鸿蒙上的用于执行 ArkTS/TS/JS 代码的标准运行时。除去上层对于 JS 标准支持(基于 Test262 测试集),同时也通过 N-API 给开发者提供了使用 C/C++ 实现更加底层能力的方案,与大部分类 Node.js 运行时保持基本一致。
不过方舟运行时与社区现有的一些实现仍然存在差异,本部分将简单列举起差异和阐述如何进行适配:
不支持 Symbol
鸿蒙不支持使用 Symbol,因此 Symbol 相关的 N-API 均被隐藏,不支持的原因参考 Symbol 适配指导
#[cfg(not(feature = "ohos"))]
pub fn create_symbol_from_js_string(&self, description: JsString) -> Result<JsSymbol> {
let mut result = ptr::null_mut();
check_status!(unsafe { sys::napi_create_symbol(self.0, description.0.value, &mut result) })?;
Ok(unsafe { JsSymbol::from_raw_unchecked(self.0, result) })
}
Note
目前使用 feature
进行隐藏,后续将修改为 target_env
。
无需 napi_adjust_external_memory
在 Node.js 中用于调整分配的外部内存计数等信息,有助于 GC 更好的分析和处理。在鸿蒙上无需额外进行调用,因此与上类似隐藏即可。
不支持 node_api_throw_syntax_error(napi9)
鸿蒙不支持,隐藏。
不支持 node_api_create_syntax_error(napi9)
鸿蒙不支持,隐藏。
不支持 experimental 相关的 N-API
鸿蒙不支持,隐藏。列表有:
- node_api_create_external_string_latin1
- node_api_create_external_string_utf16
Buffer 差异
目前 N-API 侧的 Buffer 与 ArkTS 中的 @ohos.buffer
模块并非一一对应,详情参考 Buffer。除此之外,还存在一些差异需要额外适配:
创建空 buffer 失败
目前系统对于 napi_create_buffer
底层在实现上会强行校验 length 会导致无法创建空 buffer,而目前鸿蒙系统上 buffer 与 arraybuffer 表现一致,因此暂时使用 napi_create_arraybuffer
进行替换,参考 PR
ArrayBuffer 差异
相关修复 PR
创建不允许直接传入 NULL/nullptr
鸿蒙实现上带有一些额外的参数校验或者逻辑会导致在创建空的 ArrayBuffer 的时候直接传入空指针失败,需要通过引用传入。
napi_value buf;
napi_status status = napi_create_arraybuffer(env, 0, NULL, &buf);
void *data = NULL;
napi_status status = napi_create_arraybuffer(env, 0, &data, &buf);
napi_get_typedarray_info 获取的参数含义不一致
在鸿蒙的实现上,通过napi_get_typedarray_info
获取到的 TypedArray 的 length
实际值为:数组长度 * 字节长度,因此在取值的时候需要除于对应类型的字节长度,从而获取到最终真实的长度。
napi_wrap 差异
napi_wrap 用于关联原生对象和 JS 对象。鸿蒙上的实现,当napi_ref
参数为非空时,会导致原生对象对应的析构函数或者finalize_hint
回调函数在第一次创建之后,对象销毁时无法被正常调用。
此时需要通过 napi_reference_unref
来减少引用计数来规避该问题,如果napi_ref
的参数为 NULL/nullptr 则无需额外处理。 关联 PR
napi_wrap(env,
jsThis,
reinterpret_cast<void*>(obj),
MyObject::Destructor,
nullptr, // finalize_hint
&obj->wrapper_);
napi_reference_unref(env, obj->wrapper_, nullptr);