From c5424891f169462c80a01e7c4c7c2667b9ab2ec9 Mon Sep 17 00:00:00 2001 From: kanghonglin Date: Mon, 21 Apr 2025 15:35:53 +0800 Subject: [PATCH] =?UTF-8?q?Node-API=E5=B8=B8=E8=A7=81=E9=97=AE=E9=A2=98doc?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: kanghonglin --- zh-cn/application-dev/napi/use-napi-faqs.md | 36 ++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/zh-cn/application-dev/napi/use-napi-faqs.md b/zh-cn/application-dev/napi/use-napi-faqs.md index d2ca10f2c74..b0abdb7ad39 100644 --- a/zh-cn/application-dev/napi/use-napi-faqs.md +++ b/zh-cn/application-dev/napi/use-napi-faqs.md @@ -2,17 +2,17 @@ ## ArkTS/JS侧import xxx from libxxx.so后,使用xxx报错显示undefined/not callable或明确的Error message -1. 排查.cpp文件在注册模块时的模块名称与so的名称匹配一致。 +1. 检查.cpp文件在注册模块时的模块名称与so的名称是否匹配一致。 如模块名为entry,则so的名字为libentry.so,napi_module中nm_modname字段应为entry,大小写与模块名保持一致。 -2. 排查so是否加载成功。 +2. 检查so是否加载成功。 应用启动时过滤模块加载相关日志,重点搜索"dlopen"关键字,确认是否有相关报错信息;常见加载失败原因有权限不足、so文件不存在以及so已拉入黑名单等,可根据以下关键错误日志确认问题。其中,多线程场景(worker、taskpool等)下优先检查模块实现中nm_modname是否与模块名一致,区分大小写。 -3. 排查依赖的so是否加载成功。 - 确定所依赖的其它so是否打包到应用中以及是否有权限打开。常见加载失败原因有权限不足、so文件不存在等,可根据以下关键错误日志确认问题。 +3. 检查依赖的so文件是否加载成功。 + 确定所依赖的其它so是否打包到应用中以及是否有权限打开。常见加载失败原因有权限不足、so文件不存在等,可以根据关键错误日志确认问题。 -4. 排查模块导入方式与so路径是否对应。 - 若JS侧导入模块的形式为: import xxx from '\@ohos.yyy.zzz',则该so将在/system/lib/module/yyy中找libzzz.z.so或libzzz_napi.z.so,若so不存在或名称无法对应,则报错日志中会出现dlopen相关日志。 +4. 检查模块导入方式与so路径是否对应。 + 若JS侧导入模块的形式为: import xxx from '\@ohos.yyy.zzz',该so将在/system/lib/module/yyy中找libzzz.z.so或libzzz_napi.z.so。若so不存在或名称无法对应,报错日志中会出现dlopen相关日志。 注意,32位系统路径为/system/lib,64位系统路径为/system/lib64。 @@ -21,7 +21,7 @@ | module $SO is not allowed to load in restricted runtime. | $SO表示模块名。该模块不在受限worker线程的so加载白名单,不允许加载,建议用户删除该模块。 | | module $SO is in blocklist, loading prohibited. | $SO表示模块名。受卡片或者Extension管控,该模块在黑名单内,不允许加载,建议用户删除该模块。 | | load module failed. $ERRMSG. | 动态库加载失败。$ERRMSG表示加载失败原因,一般常见原因是so文件不存在、依赖的so文件不存在或者符号未定义,需根据加载失败原因具体分析。 | -| try to load abc file from $FILEPATH failed. | 通常加载动态库和abc文件为二选一:如果是要加载动态库并且加载失败,该告警可以忽略;如果是要加载abc文件,则该错误打印的原因是abc文件不存在,$FILEPATH表示模块路径。 | +| try to load abc file from $FILEPATH failed. | 加载动态库或 abc 文件时,如果目标是动态库且加载失败,此告警可忽略;若目标是 abc 文件,则错误原因是 abc 文件不存在。$FILEPATH表示模块路径。 | 5. 如果有明确的Error message,可以通过Error message判断当前问题。 @@ -39,23 +39,23 @@ 解决此类问题有以下两种思路: -- 若该异常开发者不关心,可以选择直接清除。 - 可直接使用napi接口napi_get_and_clear_last_exception,清理异常。调用时机:在打印occur exception need return日志的接口之前调用。 +- 如果该异常对开发者不重要,可以选择直接清除。 + 可以直接使用napi接口napi_get_and_clear_last_exception来清理异常。调用时机:在打印occur exception need return日志的接口之前。 -- 将该异常继续向上抛到ArkTS层,在ArkTS层进行捕获。 - 发生异常时,可以选择走异常分支, 确保不再走多余的Native逻辑 ,直接返回到ArkTS层。 +- 将该异常继续向上传递到ArkTS层,在ArkTS层进行捕获。 + 发生异常时,可以选择走异常分支,确保不再执行与当前任务无关或重复的Native逻辑,直接返回到ArkTS层。 ## napi_value和napi_ref的生命周期有何区别 -- native_value由HandleScope管理,一般开发者不需要自己加HandleScope(uv_queue_work的complete callback除外)。 +- native_value由HandleScope管理,一般开发者不需要自行添加HandleScope(uv_queue_work的complete callback除外)。 -- napi_ref由开发者自己管理,需要手动delete。 +- napi_ref由开发者自行管理,需要手动调用delete。 ## Node-API接口返回值不是napi_ok时,如何排查定位 Node-API接口正常执行后,会返回一个napi_ok的状态枚举值,若napi接口返回值不为napi_ok,可从以下几个方面进行排查。 -- Node-API接口执行前一般会进行入参校验,首先进行的是判空校验。在代码中体现为: +- Node-API接口执行前通常会进行入参校验,首先进行判空校验。具体代码如下: ```cpp CHECK_ENV: env判空校验 @@ -68,7 +68,7 @@ Node-API接口正常执行后,会返回一个napi_ok的状态枚举值,若na RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_NUMBER, napi_number_expected); ``` -- 还有一些接口会对其执行结果进行校验。比如napi_call_function这个接口,其功能是执行一个JS function,当JS function中出现异常时,Node-API将会返回napi_pending_exception的状态值。 +- 还有一些接口会校验执行结果。例如napi_call_function接口用于执行JS函数,如果JS函数中出现异常,Node-API将会返回napi_pending_exception的状态值。 ```cpp auto resultValue = engine->CallFunction(nativeRecv, nativeFunc, nativeArgv, argc); @@ -79,9 +79,9 @@ Node-API接口正常执行后,会返回一个napi_ok的状态枚举值,若na ## napi_threadsafe_function内存泄漏,应该如何处理 -`napi_threadsafe_function`(下文简称tsfn)在使用时,常常会调用 `napi_acquire_threadsafe_function` 来更改tsfn的引用计数,确保tsfn不会意外被释放。但在使用完成后,应该及时使用 `napi_tsfn_release` 模式调用 `napi_release_threadsafe_function` 方法,以确保在所有调用回调都执行完成后,其引用计数能回归到调用 `napi_acquire_threadsafe_function` 方法之前的水平。当其引用计数归为0时,tsfn才能正确的被释放。 +`napi_threadsafe_function`(下文简称tsfn)在使用时,通常会调用 `napi_acquire_threadsafe_function` 来更改tsfn的引用计数,确保tsfn不会意外被释放。使用完成后,应该及时使用 `napi_tsfn_release` 模式调用 `napi_release_threadsafe_function` 方法,以确保在所有调用回调都执行完成后,其引用计数能回归到调用 `napi_acquire_threadsafe_function` 方法之前的水平。当其引用计数归为0时,tsfn才能正确的被释放。 -当在env即将退出,但tsfn的引用计数未被归零时,应该使用 `napi_tsfn_abort` 模式调用 `napi_release_threadsafe_function` 方法,确保在env释放后不再对tsfn进行持有及使用。在env退出后,继续持有tsfn进行使用,是一种未定义的行为,可能会触发崩溃。 +当env即将退出且tsfn的引用计数未归零时,应该使用 `napi_tsfn_abort` 模式调用 `napi_release_threadsafe_function` 方法,确保在env释放后不再对tsfn进行持有及使用。在env退出后,继续持有tsfn进行使用,是一种未定义的行为,可能会触发崩溃。 如下代码将展示通过注册 `env_cleanup` 钩子函数的方式,以确保在env退出后不再继续持有tsfn。 @@ -228,7 +228,7 @@ napi_value MyTsfnDemo(napi_env env, napi_callback_info info) { }; ``` -以下内容为主线程逻辑,主要用作创建worker线程和通知worker执行任务 +以下内容为主线程逻辑,主要用于创建worker线程并通知其执行任务。 ```ts // 主线程 Index.ets -- Gitee