Skip to content

Commit d80afa0

Browse files
committed
n-api介绍
1 parent 2d9b0b7 commit d80afa0

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed

进阶/node8-napi.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
## N-API简介
2+
3+
Node.js 8.0 在2017年6月份发布,升级的特性中,包含了N-API。编写过或者使用过 node扩展的同学,不少都遇到过升级node版本,node扩展编译失败的情况,因为node扩展严重依赖于V8暴露的API,而node不同版本依赖的V8版本可能不同,一旦升级node版本,原先运行正常的node扩展就编译失败了。
4+
5+
这种情况对node生态圈无疑是不利的,N-API的引入正是试图改善这种情况的一种尝试。它跟底层JS引擎无关,只要暴露的API足够稳定,那么node扩展的编写者就不用过分担忧node的升级问题。
6+
7+
## 如何使用N-API
8+
9+
先强调一点,N-API并不是对原有node扩展实现方式的替代,它只是提供了一系列底层无关的API,来帮助开发者编写跨版本的node扩展。至于如何编写、编译扩展,跟原来的差不多。
10+
11+
本文会从一个超级简单的例子,简单介绍N-API的使用。
12+
13+
## 环境准备
14+
15+
首先,N-API是8.0版本引入的,首先确保本地安装了8.0版本。笔者用的是`nvm`,读者可自行选择安装方式。
16+
17+
```bash
18+
nvm i 8.0
19+
nvm use 8.0
20+
```
21+
22+
然后,安装`node-gyp`,编译扩展会用到。
23+
24+
```bash
25+
npm install -g node-gyp
26+
```
27+
28+
创建项目目录,并初始化`package.json`
29+
30+
```bash
31+
mkdir hello & cd hello # 目录名随便起
32+
npm init -f
33+
```
34+
35+
36+
## 编写扩展
37+
38+
创建`hello.cc`作为扩展的源文件。
39+
40+
```bash
41+
mkdir src
42+
touch src/hello.cc
43+
```
44+
45+
编辑`hello.cc`,输入如下内容。
46+
47+
```c
48+
#include <node_api.h>
49+
50+
// 实际暴露的方法,这里只是简单返回一个字符串
51+
napi_value HelloMethod (napi_env env, napi_callback_info info) {
52+
napi_value world;
53+
napi_create_string_utf8(env, "world", 5, &world);
54+
return world;
55+
}
56+
57+
// 扩展的初始化方法,其中
58+
// env:环境变量
59+
// exports、module:node模块中对外暴露的对象
60+
void Init (napi_env env, napi_value exports, napi_value module, void* priv) {
61+
// napi_property_descriptor 为结构体,作用是描述扩展暴露的 属性/方法 的描述
62+
napi_property_descriptor desc = { "hello", 0, HelloMethod, 0, 0, 0, napi_default, 0 };
63+
napi_define_properties(env, exports, 1, &desc); // 定义暴露的方法
64+
}
65+
66+
NAPI_MODULE(hello, Init); // 注册扩展,扩展名叫做hello,Init为扩展的初始化方法
67+
```
68+
69+
## 编译扩展
70+
71+
首先,创建编译描述文件`binding.gyp`。
72+
73+
```json
74+
{
75+
"targets": [
76+
{
77+
"target_name": "hello",
78+
"sources": [ "./src/hello.cc" ]
79+
}
80+
]
81+
}
82+
```
83+
84+
然后,运行如下命令进行编译。
85+
86+
```bash
87+
node-gyp rebuild
88+
```
89+
90+
## 调用扩展
91+
92+
未方便调用扩展,先安装`bindings`
93+
94+
```bash
95+
npm install --save bindings
96+
```
97+
98+
然后,创建`app.js`,调用刚编译的扩展。
99+
100+
```javascript
101+
var addon = require('bindings')('hello');
102+
103+
console.log( addon.hello() ); // world
104+
```
105+
106+
运行代码,由于N-API当前尚处于Experimental阶段,记得加上`--napi-modules`标记。
107+
108+
```bash
109+
node --napi-modules app.js
110+
```
111+
112+
输出如下
113+
114+
```bash
115+
{"path":"/data/github/abi-stable-node-addon-examples/1_hello_world/napi/build/Release/hello.node"}
116+
world
117+
(node:6500) Warning: N-API is an experimental feature and could change at any time.
118+
```
119+
120+
## 相关链接
121+
122+
https://nodejs.org/api/n-api.html

0 commit comments

Comments
 (0)