Node.jsのN-APIをv8.7でWindowsで試した

# 参考資料

- https://hackernoon.com/n-api-and-getting-started-with-writing-c-addons-for-node-js-cf061b3eae75

```shell-session
git clone https://github.com/schahriar/n-api-article.git
cd n-api-article\Getting_Started
```

# 上記の資料だとビルドエラー

```txt
C:\Users\kjunichi\Documents\work\nodejs\n-api-article\Getting_Started>node-gyp configure build
gyp info it worked if it ends with ok
gyp info using node-gyp@3.6.2
gyp info using node@8.7.0 | win32 | x64
gyp http GET https://nodejs.org/download/release/v8.7.0/node-v8.7.0-headers.tar.gz
gyp http 200 https://nodejs.org/download/release/v8.7.0/node-v8.7.0-headers.tar.gz
gyp http GET https://nodejs.org/download/release/v8.7.0/SHASUMS256.txt
gyp http GET https://nodejs.org/download/release/v8.7.0/win-x86/node.lib
gyp http GET https://nodejs.org/download/release/v8.7.0/win-x64/node.lib
gyp http 200 https://nodejs.org/download/release/v8.7.0/SHASUMS256.txt
gyp http 200 https://nodejs.org/download/release/v8.7.0/win-x86/node.lib
gyp http 200 https://nodejs.org/download/release/v8.7.0/win-x64/node.lib
gyp info spawn C:\Python27\python.EXE
gyp info spawn args [ 'C:\\Users\\kjunichi\\AppData\\Roaming\\nvm\\v8.7.0\\node_modules\\node-gyp\\gyp\\gyp_main.py',
gyp info spawn args   'binding.gyp',
gyp info spawn args   '-f',
gyp info spawn args   'msvs',
gyp info spawn args   '-G',
gyp info spawn args   'msvs_version=auto',
gyp info spawn args   '-I',
gyp info spawn args   'C:\\Users\\kjunichi\\Documents\\work\\nodejs\\n-api-article\\Getting_Started\\build\\config.gypi',
gyp info spawn args   '-I',
gyp info spawn args   'C:\\Users\\kjunichi\\AppData\\Roaming\\nvm\\v8.7.0\\node_modules\\node-gyp\\addon.gypi',
gyp info spawn args   '-I',
gyp info spawn args   'C:\\Users\\kjunichi\\.node-gyp\\8.7.0\\include\\node\\common.gypi',
gyp info spawn args   '-Dlibrary=shared_library',
gyp info spawn args   '-Dvisibility=default',
gyp info spawn args   '-Dnode_root_dir=C:\\Users\\kjunichi\\.node-gyp\\8.7.0',
gyp info spawn args   '-Dnode_gyp_dir=C:\\Users\\kjunichi\\AppData\\Roaming\\nvm\\v8.7.0\\node_modules\\node-gyp',
gyp info spawn args   '-Dnode_lib_file=C:\\Users\\kjw_j\\.node-gyp\\8.7.0\\<(target_arch)\\node.lib',
gyp info spawn args   '-Dmodule_root_dir=C:\\Users\\kjunichi\\Documents\\work\\nodejs\\n-api-article\\Getting_Started',
gyp info spawn args   '-Dnode_engine=v8',
gyp info spawn args   '--depth=.',
gyp info spawn args   '--no-parallel',
gyp info spawn args   '--generator-output',
gyp info spawn args   'C:\\Users\\kjunichi\\Documents\\work\\nodejs\\n-api-article\\Getting_Started\\build',
gyp info spawn args   '-Goutput_dir=.' ]
gyp info spawn msbuild
gyp info spawn args [ 'build/binding.sln',
gyp info spawn args   '/clp:Verbosity=minimal',
gyp info spawn args   '/nologo',
gyp info spawn args   '/p:Configuration=Release;Platform=x64' ]
このソリューション内のプロジェクトを 1 度に 1 つずつビルドします。並行ビルドを有効にするには、"/m" スイッチを追加してく
ださい。
  module.c
..\src\module.c(34): warning C4047: '関数': 間接参照のレベルが 'std::size_t' と 'napi_value (__cdecl *)(napi_env,napi_ca
llback_info
)' で異なっています。 [C:\Users\kjunichi\Documents\work\nodejs\n-api-article\Getting_Started\build\module.vcxproj]
..\src\module.c(34): warning C4024: 'napi_create_function': の型が 3 の仮引数および実引数と異なります。 [C:\Users\kjunichi\
Documents\work\node
js\n-api-article\Getting_Started\build\module.vcxproj]
..\src\module.c(34): error C2198: 'napi_create_function': 呼び出しに対する引数が少なすぎます。 [C:\Users\kjunichi\Documents
\work\nodejs\n-ap
i-article\Getting_Started\build\module.vcxproj]
..\src\module.c(45): warning C4113: 'void (__cdecl *)(napi_env,napi_value,napi_value,void *)' はパラメーター リストが 'n
api_addon_
register_func' と異なります。 [C:\Users\kjunichi\Documents\work\nodejs\n-api-article\Getting_Started\build\module.vcxproj]
..\src\module.c(45): warning C4047: '初期化中': 間接参照のレベルが 'napi_addon_register_func' と 'void (__cdecl *)(napi_
env,napi_valu
e,napi_value,void *)' で異なっています。 [C:\Users\kjunichi\Documents\work\nodejs\n-api-article\Getting_Started\build\modul
e.vcxpro
j]
gyp ERR! build error
gyp ERR! stack Error: `msbuild` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onExit (C:\Users\kjunichi\AppData\Roaming\nvm\v8.7.0\node_modules\node-gyp\lib\build.js:258:23)
gyp ERR! stack     at emitTwo (events.js:125:13)
gyp ERR! stack     at ChildProcess.emit (events.js:213:7)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:200:12)
gyp ERR! System Windows_NT 10.0.15063
gyp ERR! command "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\node-gyp\\bin\\node-gyp.js" "configure" "build"
gyp ERR! cwd C:\Users\kjunichi\Documents\work\nodejs\n-api-article\Getting_Started
gyp ERR! node -v v8.7.0
gyp ERR! node-gyp -v v3.6.2
gyp ERR! not ok
```

# 参考資料その２

- https://nodejs.org/api/n-api.html#n_api_napi_status

# 対応

```c
status = napi_create_function(env, "my_function", -1, MyFunction, NULL,&fn);
```

と、napi_create_functionを変更。

# 実行結果

```
C:\Users\kjunichi\Documents\work\nodejs\n-api-article\Getting_Started>node module.js
8 times 2 equals 16
(node:21596) Warning: N-API is an experimental feature and could change at any time.

C:\Users\kjunichi\Documents\work\nodejs\n-api-article\Getting_Started>
```

# まとめ

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">node.jsのN-APIって8.6と8.7でも互換性ないっぽい、見つけたサンプルの解説だと8.6に対応と追記があったが、8.7だとダメだった。公式ページのAPIの解説読んでパラメータ合わせたら動いた。そしたら、N-APIは実験的な機能なのでいつでも変更するとの警告。なるほど</p>&mdash; kjunichi (@kjunichi) <a href="https://twitter.com/kjunichi/status/920048334961762304?ref_src=twsrc%5Etfw">2017年10月16日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

# 関連記事

- [N-APIはホントにV8以外のJavaScriptエンジンでもリビルドなしでネイティブモジュールが動くのか](https://abrakatabura.hatenablog.com/entry/2018/12/16/000424)
- [NAPI版のnode-ffi-napiを使ってNode.jsからPythonを動かす](https://abrakatabura.hatenablog.com/entry/2019/09/30/234848)