N-API

N-API

N-API(N是一个字母,然后是API)是用于构建本机插件的API。它独立于底层JavaScript运行时(例如V8)。并作为Node.js本身的一部分。此API将作为跨Node.js版本已编译的应用程序接口(Application Binary Interface)的稳定版,简称(ABI)。它是为了将Addons插件和底层JavaScript引擎的改动隔离开来,并且允许在一个版本编译的模块不需要重新编译就可以在更高版本的Node.js上运行。ABI稳定版指南中提供了更深入的说明。

Addons插件使用和C++ Addons章节中提到的相同的方法和工具进行编译和打包。唯一的区别是原始代码使用的API集。不使用V8或Native Abstractions for Node.js API,而是使用N-API中可用的功能。

N-API暴露的API通常是用来创建和操作JavaScript的values。概念和操作通常映射到ECMA262语言规范中指定的思想。这些API具有以下属性:

  • 所有N-API调用都返回一个 napi_status 类型的状态代码。此状态表示API调用是成功还是失败。
  • API的返回值通过一个out参数传递。
  • 所有javascript的值都抽象成一个隐晦的 napi_value 类型。
  • 如果出现错误状态代码,使用napi_get_last_error_info可以获得额外的错误信息。
  • 错误处理章节中能找到更多的错误处理信息。

N-API是一个C语言的API,它确保了node.js版本和不同编译器级别之间应用程序接口(ABI)的稳定性。C++ API可以更容易使用。为了支持使用C++,这个项目使用了一个C++包装器模块叫做node-addon-api。这个包装器提供了一个可内联的C++ API。使用node-addon-api构建的二进制文件将依赖于Node.js导出的基于C函数符号的N-API接口。node-addon-api是一种更有效写代码的方法,用来编写调用N-API。举个例子,根据下面的 node-addon-api代码。第一部分展示了node-addon-api代码,第二部分
展示了addon插件中实际上的调用。

Object obj = Object::New(env);
obj["foo"] = String::New(env, "bar");
napi_status status;
napi_value object, string;
status = napi_create_object(env, &object);
if (status != napi_ok) {
  napi_throw_error(env, ...);
  return;
}

status = napi_crate_string_utf8(env, "bar", NAPI_AUTO_LENGTH, &string);
if (status != napi_ok) {
  napi_throw_error(env, ...);
  return;
}

status = napi_set_named_property(env, object, "foo", string);
if (status != napi_ok) {
  napi_throw_error(env, ...);
  return;
}

最终结果是,addon插件只使用导出的C的API。因此,它仍然获得了C API提供的ABI稳定性的好处。

当使用node-addon-api而不是C API时,可以阅读node-addon-api的API文档

要在 Node.js 中使用其他 C 库,可以使用 N-API 提供的接口。 1. 首先,你需要在你的 C 代码中包含所需的库的头文件,并将其编译为共享库。可以使用 Makefile 或其他构建工具来自动化这个过程。 2. 接下来,你需要使用 N-API 提供的接口来创建一个 Node.js 模块,并在其中加载你的 C 库。这个过程包括以下几个步骤: - 使用 `napi_module_define` 函数定义一个模块对象。 - 在模块对象中添加导出函数,这些函数将包装你的 C 函数并使其可以从 JavaScript 中调用。 - 在模块初始化函数中加载你的 C 库,通常使用 `dlopen` 函数。 下面是一个简单的示例代码,演示如何使用 N-API 来加载一个名为 `mylib` 的 C 库: ```c #include <node_api.h> #include <stdlib.h> #include <stdio.h> #include "mylib.h" napi_value my_c_function(napi_env env, napi_callback_info info) { // 将 N-API 参数转换为 C 参数 int argc = 1; napi_value argv[1]; napi_get_cb_info(env, info, &argc, argv, NULL, NULL); int arg; napi_get_value_int32(env, argv[0], &arg); // 调用你的 C 函数 int result = my_function(arg); // 将结果转换为 N-API 值并返回 napi_value ret; napi_create_int32(env, result, &ret); return ret; } napi_value Init(napi_env env, napi_value exports) { // 定义模块对象并添加导出函数 napi_property_descriptor desc[] = { {"my_c_function", NULL, my_c_function, NULL, NULL, NULL, napi_default, NULL}, }; napi_define_properties(env, exports, 1, desc); // 加载 C 库 void* handle = dlopen("libmylib.so", RTLD_LAZY); return exports; } NAPI_MODULE(NODE_GYP_MODULE_NAME, Init) ``` 这个示例中,我们定义了一个名为 `my_c_function` 的导出函数,它将一个整数作为参数传入 `my_function` 函数中,并将结果转换为 N-API 值返回。然后我们使用 `napi_define_properties` 函数将这个函数添加到模块对象中。最后,我们在模块初始化函数中使用 `dlopen` 函数加载 `libmylib.so` 库。 需要注意的是,这个示例中使用的是 Linux 下的动态链接库。如果你在其他操作系统上运行,可能需要使用不同的加载函数来加载库。另外,如果你的 C 库中使用了其他的第三方库,也需要将这些库一起编译为共享库,并将它们加载到 Node.js 模块中。 希望这个示例能够帮助你了解如何在 Node.js 中使用其他 C 库。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值