# NAPI组件 - [简介](#section11660541593) - [目录](#section161941989596) - [使用场景](#section11759141594811) - [接口说明](#section1611515555510) - [开发步骤](#section937267212) - [相关仓](#section3970193518214) ## 简介 NAPI(Native API)组件是一套对外接口基于Node.js N-API规范开发的原生模块扩展开发框架。 **图 1** NAPI组件架构图 ![](figures/zh-cn_image_0000001162437581.jpg) - **NativeEngine** JS引擎抽象层,统一JS引擎在NAPI层的接口行为。 - **ModuleManager** 管理模块,用于模块加载、模块信息缓存。 - **ScopeManager** 管理NativeValue的生命周期。 - **ReferenceManager** 管理NativeReference的生命周期。 ## 目录 NAPI组件源代码在/foundation/arkui/napi下,目录结构如下图所示: ``` foundation/arkui/napi ├── interfaces │ └── kits │ └── napi # NAPI头文件目录 ├── module_manager # 模块管理 ├── native_engine # NativeEngine抽象层 │ └── impl │ └── ark # 基于Ark的NativeEngine实现 ├── scope_manager # 作用域管理 └── test # 测试目录 ``` ## 使用场景 NAPI适合封装IO、CPU密集型、OS底层等能力并对外暴露JS接口,通过NAPI可以实现JS与C/C++代码互相访问。我们可以通过NAPI接口构建例如网络通信、串口访问、多媒体解码、传感器数据收集等模块。 ## 接口说明 接口实现详见:**foundation/arkui/napi**。 **表 1** NAPI接口说明

接口分类

描述

模块注册

向模块管理注册模块信息的接口。

异常&错误处理

向JS抛出异常。

对象生命周期管理

作用域管理,用于限定某个作用域范围内的NAPI对象的生命周期。

创建JS对象

创建标准的对象类型。

C类型转NAPI类型

C到NAPI的类型转换。

NAPI类型转C类型

NAPI到C的类型转换。

获取全局实例的函数

获取全局实例。

JS值的操作

===、typeof、instanceof等操作符的NAPI接口。

JS对象的属性操作

操作对象属性函数集。

JS函数的操作

方法调用、实例创建。

对象封装

绑定JS对象的外部上下文关系。

简单异步

创建异步任务。

promise

创建promise对象的函数集。

脚本运行

运行JS代码。

## 开发步骤 下面以开发一个获取应用包名的JS接口为例介绍如何使用NAPI。 我们要实现的JS接口原型是: ``` function getAppName(): string; ``` 以下是实现源码: ``` // app.cpp #include #include #include "napi/native_api.h" #include "napi/native_node_api.h" struct AsyncCallbackInfo { napi_env env; napi_async_work asyncWork; napi_deferred deferred; }; // getAppName对应的C/C++实现函数 napi_value JSGetAppName(napi_env env, napi_callback_info info) { napi_deferred deferred; napi_value promise; // 创建promise NAPI_CALL(env, napi_create_promise(env, &deferred, &promise)); AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo { .env = env, .asyncWork = nullptr, .deferred = deferred, }; napi_value resourceName; napi_create_string_latin1(env, "GetAppName", NAPI_AUTO_LENGTH, &resourceName); // 创建异步任务队列 napi_create_async_work( env, nullptr, resourceName, // 异步任务的回调 [](napi_env env, void* data) {}, // 异步任务结束后的回调 [](napi_env env, napi_status status, void* data) { AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data; napi_value appName; const char* str = "com.example.helloworld"; napi_create_string_utf8(env, str, strlen(str), &appName); // 触发回调 napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, appName); napi_delete_async_work(env, asyncCallbackInfo->asyncWork); delete asyncCallbackInfo; }, (void*)asyncCallbackInfo, &asyncCallbackInfo->asyncWork); napi_queue_async_work(env, asyncCallbackInfo->asyncWork); return promise; } // 模块导出入口函数 static napi_value AppExport(napi_env env, napi_value exports) { static napi_property_descriptor desc[] = { DECLARE_NAPI_FUNCTION("getAppName", JSGetAppName), }; NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); return exports; } // app模块描述 static napi_module appModule = { .nm_version = 1, .nm_flags = 0, .nm_filename = nullptr, .nm_register_func = AppExport, .nm_modname = "app", .nm_priv = ((void*)0), .reserved = {0} }; // 注册模块 extern "C" __attribute__((constructor)) void AppRegister() { napi_module_register(&appModule); } ``` 对应编译脚本的实现: ``` // BUILD.gn import("//build/ohos.gni") ohos_shared_library("app") { # 指定编译源文件 sources = [ "app.cpp", ] # 指定编译依赖 deps = [ "//foundation/arkui/napi:ace_napi" ] # 指定库生成的路径 relative_install_dir = "module" subsystem_name = "arkui" part_name = "napi" } ``` 应用中的JS测试代码: ``` import app from '@ohos.app' export default { testGetAppName() { app.getAppName().then(function (data) { console.info('app name: ' + data); }); } } ``` ## 相关仓 [ArkUI框架子系统](https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/ArkUI%E6%A1%86%E6%9E%B6%E5%AD%90%E7%B3%BB%E7%BB%9F.md) [arkui\_ace\_engine](https://gitee.com/openharmony/arkui_ace_engine) [arkui\_ace\_engine\_lite](https://gitee.com/openharmony/arkui_ace_engine_lite) **arkui\_napi**