【HarmonyOS NAPI 深度探索7】N-API 数据处理:与 JavaScript 数据的交互

【HarmonyOS NAPI 深度探索7】N-API 数据处理:与 JavaScript 数据的交互

在开发原生模块时,一个核心的需求就是与 JavaScript 数据交互。N-API 提供了丰富的工具,让你能够方便地处理各种类型的数据,从基础的字符串、数字到复杂的对象和数组。本文我们将通过实例化讲解如何在 N-API 中进行数据处理。

N-API 支持的基本数据类型

N-API 支持多种 JavaScript 数据类型的创建和操作,包括:

  1. 基本类型:如字符串、数字、布尔值等。
  2. 复合类型:如对象、数组、函数等。
  3. 特殊类型 :如 PromiseBufferDate 等。

通过 N-API,可以轻松实现这些类型的互相转换和操作。

与 JavaScript 数据交互的基本操作

在 N-API 中,数据处理主要通过 Napi 命名空间提供的类和方法完成。下面通过几个具体示例来展示如何操作各种数据类型。

示例 1:处理字符串

字符串是最常用的数据类型之一。以下代码展示了如何在原生模块中接收字符串参数,并返回一个处理后的结果:

cpp 复制代码
#include <napi.h>

Napi::String ProcessString(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();

    if (info.Length() < 1 || !info[0].IsString()) {
        Napi::TypeError::New(env, "String expected").ThrowAsJavaScriptException();
        return Napi::String::New(env, "");
    }

    std::string input = info[0].As<Napi::String>();
    std::string result = "Hello, " + input;

    return Napi::String::New(env, result);
}

Napi::Object Init(Napi::Env env, Napi::Object exports) {
    exports.Set("processString", Napi::Function::New(env, ProcessString));
    return exports;
}

NODE_API_MODULE(napi_example, Init)

运行以下测试代码:

javascript 复制代码
const addon = require('./build/Release/napi_example');
console.log(addon.processString("HarmonyOS")); // 输出:Hello, HarmonyOS

这里主要通过Napi::String::New 创建TS字符串,然后返回给TS。

示例 2:处理数字

N-API 也可以用来接收和返回数字。例如,我们可以实现一个简单的加法函数:

cpp 复制代码
Napi::Number AddNumbers(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();

    if (info.Length() < 2 || !info[0].IsNumber() || !info[1].IsNumber()) {
        Napi::TypeError::New(env, "Two numbers expected").ThrowAsJavaScriptException();
        return Napi::Number::New(env, 0);
    }

    double num1 = info[0].As<Napi::Number>().DoubleValue();
    double num2 = info[1].As<Napi::Number>().DoubleValue();
    return Napi::Number::New(env, num1 + num2);
}

通过以下代码测试:

javascript 复制代码
const addon = require('./build/Release/napi_example');
console.log(addon.addNumbers(5, 3)); // 输出:8
示例 3:处理对象

N-API 允许你操作 JavaScript 对象,可以创建对象或访问和修改其属性:

cpp 复制代码
Napi::Object CreateObject(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    Napi::Object obj = Napi::Object::New(env);

    obj.Set("name", "HarmonyOS");
    obj.Set("version", 1.0);

    return obj;
}

测试代码:

javascript 复制代码
const addon = require('./build/Release/napi_example');
console.log(addon.createObject()); // 输出:{ name: 'HarmonyOS', version: 1 }
示例 4:处理数组

数组的操作同样简单,可以创建数组或访问其元素:

cpp 复制代码
Napi::Array CreateArray(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    Napi::Array arr = Napi::Array::New(env);

    arr.Set(uint32_t(0), "Harmony");
    arr.Set(uint32_t(1), "OS");
    arr.Set(uint32_t(2), "NAPI");

    return arr;
}

测试代码:

javascript 复制代码
const addon = require('./build/Release/napi_example');
console.log(addon.createArray()); // 输出:[ 'Harmony', 'OS', 'NAPI' ]
示例 5:异步数据处理

N-API 也支持异步数据处理,可以通过 Promise 将原生操作结果返回到 JavaScript:

cpp 复制代码
Napi::Value AsyncOperation(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();

    return Napi::Promise::Deferred::New(env).Promise();
}

异步操作的具体实现可以结合线程池或事件循环完成。

napi.h与node_api.h

文本使用的api都是基于napi.h头文件提供的接口,napi.h依赖node_api.h,在HarmonyOS Next开发中用到node_api.h相关方法,后面会逐步介绍。这里简单说明一下两个头文件的区别。

  • npai.h
    • -napi.h是 Node.js 的 N - API(Node.js API for Native Modules)的头文件。N - API 是一个用于构建原生 Node.js 模块的稳定 ABI(Application Binary Interface)层。
    • 它的主要目的是提供一个稳定的接口,使得原生模块可以在不同版本的 Node.js 运行时上无需重新编译就能工作。例如,当 Node.js 从版本 12 升级到版本 14 时,如果一个原生模块是使用 N - API 编写的(通过napi.h),只要该模块使用的 N - API 版本在两个 Node.js 版本中都受支持,就可以继续正常使用,而不需要修改和重新编译代码。
    • N - API 抽象了 Node.js 的内部实现细节,开发者可以使用一组标准化的函数来操作 JavaScript 值、创建对象、调用函数等。例如,napi_create_object函数可以用于在原生代码中创建一个 JavaScript 对象,这种操作方式在不同的 Node.js 版本中是相对稳定的。
  • node_api.h
    • node_api.h在早期的 Node.js 原生模块开发中被使用。它与napi.h相比,没有提供像 N - API 那样稳定的 ABI。
    • 其接口与 Node.js 内部的 JavaScript 运行时(如 V8 引擎)的联系更紧密,并且可能会因为 Node.js 内部实现的变化而发生改变。例如,在 Node.js 版本升级过程中,如果 V8 引擎的某些底层接口发生了修改,使用node_api.h编写的原生模块可能需要进行相应的调整和重新编译才能继续正常工作。
      在napi项目中napi.h头文件位于node_modules下面:
总结

N-API 提供了一套强大的 API,支持与 JavaScript 各种数据类型的交互。无论是字符串、数字这样的简单类型,还是对象、数组这样的复杂类型,甚至是异步数据处理,N-API 都能轻松应对。通过这些工具,你可以将复杂的底层逻辑封装到原生模块中,并在 JavaScript 中方便地调用它们。

相关推荐
TDengine (老段)23 分钟前
TDengine 中的关联查询
大数据·javascript·网络·物联网·时序数据库·tdengine·iotdb
再学一点就睡1 小时前
大文件上传之切片上传以及开发全流程之前端篇
前端·javascript
Merokes2 小时前
关于Gstreamer+MPP硬件加速推流问题:视频输入video0被占用
c++·音视频·rk3588
请来次降维打击!!!3 小时前
优选算法系列(5.位运算)
java·前端·c++·算法
别NULL3 小时前
机试题——统计最少媒体包发送源个数
c++·算法·媒体
難釋懷4 小时前
JavaScript基础-移动端常见特效
开发语言·前端·javascript
嘤国大力士4 小时前
C++11&QT复习 (七)
java·c++·qt
背影疾风4 小时前
C++学习之路:指针基础
c++·学习
x-cmd4 小时前
[250331] Paozhu 发布 1.9.0:C++ Web 框架,比肩脚本语言 | DeaDBeeF 播放器发布 1.10.0
android·linux·开发语言·c++·web·音乐播放器·脚本语言
还是鼠鼠4 小时前
Node.js全局生效的中间件
javascript·vscode·中间件·node.js·json·express