Node.js のモジュールをC++で書く際のメモ(2)

第1回から9ヶ月もたち、Node.jsの方もAPIに変更があったのでC++ Addon関連のメモをしておく。

バージョン関連

Nodeのバージョンによって処理を変える

node_version.hに定数、マクロが定義されているのでこれを利用する。

#include <node.h>
#include <node_version.h>

#if NODE_VERSION_AT_LEAST(0,5,0)
    //Node v0.5.0以上の場合
#else
    //Node v0.5.0未満の場合
#endif

横着したい場合は

#if NODE_MINOR_VERSION > 4
    // マイナーバージョンが4より大きい場合
#endif
バージョン文字列の取得
std::string version = NODE_VERSION_STRING;

eio_custom() のプロトタイプが変更

EIOスレッドを処理を実行するためのeio_custom()のプロトタイプが変更されている。
これに対応するため、eio_custom()の第一引数に渡す関数のプロトタイプを変更する必要がある

Node v0.5.3まで:

typedef int (*eio_cb)(eio_req *req);
...
eio_req *eio_custom(eio_cb execute, int pri, eio_cb cb, void *data);

Node v0.5.4以降:

typedef int (*eio_cb)(eio_req *req);
...
eio_req *eio_custom(void (*execute)(eio_req *), int pri, eio_cb cb, void *data);

C++からnode::EventEmitter使用不可

Node v0.5.2でnode::EventEmitterが削除されているため、代替手段をとる必要がある。
ドキュメントでは代わりにnode::MakeCallback()を使用することを推奨している。

node::MakeCallback(this->object, "someevent", 2, argv);

他の方法はこちらが参考になる。

ビルド時に作成されるディレクトリ名の変更

Node v0.5.5から`node-waf build`を実行した際に作成されるディレクトリ名が変更になっている。
以前は $builddir/default だったものが $builddir/Release に変わっている。

対応方法としては、Addonを直接requireせず、以下のようなJavaScriptを用いる方法がある

var binding;
try{
  binding = require(__dirname + '/../build/Release/hoge');
}catch(e){
  binding = require(__dirname + '/../build/default/hoge');  
}

process.versionでパターンマッチするとかwscriptでバージョンを判別して適切なパスにsymlinkを貼るなど他の方法もある