LoginSignup
4
7

More than 5 years have passed since last update.

C言語によるNode.jsのモジュール開発 v8のまとめ

Posted at

C言語によるNode.jsのモジュール開発 v8のまとめ

v8はC言語のライブラリをNode.jsと接続することが出来るライブラリです。
Raspberry PiがJessieからStrechにバージョンアップして、Node.jsのバージョンが0.12系から4.8.6に上がり、C++アドオンであるv8の仕様も大幅に変わりました。

C++アドオンを一つのファイルでJessieとStrechの両方に対応したいと思っていたらできましたので、そのやり方を解説します。

開発したソースコードはこちらにあるlazurite_wrap.ccです。

この中を部分的に切り出して差異の説明をします。

バージョンを取得する

33行目あたり...
V8_MAJOR_VERSIONでバージョンを取得できます。
JessieはV8_MAJOR_VERSIONがありませんので、#elseでV8_VER_0を宣言して、Versionが4のときとVersionが5のときに、V8_VER_5を宣言しています。
以降、ソースコードの本体ではV8_VER_0とV8_VER_5でバージョンを識別していきます。

lazurite_wrap.cc
#include <v8.h>
#include "liblazurite.h"

#if (V8_MAJOR_VERSION == 4)
    #define V8_VER_5
#elif (V8_MAJOR_VERSION == 5)
    #define V8_VER_5
#else
    #define V8_VER_0
#endif

関数の宣言

関数の宣言部分はこのように異なります。
戻り値の指定方法と、引数を取得するargsの宣言が両方共異なります。

lazurite_wrap.cc
#ifdef V8_VER_0
static Handle<Value> dlopen(const Arguments& args) {
    HandleScope scope;
#endif
#ifdef V8_VER_5
static void dlopen(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();
#endif

Nodeに渡す変数の生成

isolateの引数が追加になっています。
また、文字列の宣言が変わっています。

(補足) strはchar*です。string型ではありません。

データ型 v4系 V0系
文字列 String::NewFromUtf8(isolate,str); String::New(str)
Integer型 Integer::New(isolate,int_data); Integer::New(int_data);
Boolean型 Boolean::New(isolate,bool_data); Boolean::New(bool_data);
uint32_t型 Uint32::New(isolate,uint32_data); Uint32::New(uint32_data);
配列 Localpacket_array = Array::New(isolate); Localpacket_array = Array::New()
JSON Local obj = Object::New(isolate); Local obj = Object::New();

引数の取得

それぞれ引数が順番に、以下のように指定されているとします。
args[0] 小数点を含む数値
args[1] Boolean
args[2] Integer
args[3] 文字列
args[3] 配列

これらの値を取り出す方法は値を取得する方法は次のとおりです。
これは、バージョンによる違いはありません。

lazurite_wrap.cc
double double_data = args[0]->NumberValue();
bool bool_data = args[1]->BooleanValue();
int int_data = args[2]->IntegerValue();
String::Utf8Value str(args[3]->ToString());
Local<Array> arr = Local<Array>::Cast(args[4]);

戻り値

戻り値の返し方は大きく異なります。

v0.12系はreturnで返すのに対して、v4.8.6ではargsにセットして関数を抜けます。
また、戻り値をセットするときに、isolateの引数が追加になっています。

lazurite_wrap.cc
#ifdef V8_VER_0
    return scope.Close(Boolean::New(true));
#endif
#ifdef V8_VER_5
    args.GetReturnValue().Set(Boolean::New(isolate,true));
    return;
#endif
}

JSONオブジェクトの作成方法

JSONのkeyの宣言方法が異なっています。

lazurite_wrap.cc
#ifdef V8_VER_0
    Local<Object> obj = Object::New();
    obj->Set(String::NewSymbol("payload"),String::New(str));
#endif
#ifdef V8_VER_5
    Local<Object> obj = Object::New(isolate);
    obj->Set(String::NewFromUtf8(isolate,"payload"),String::NewFromUtf8(isolate,str));

#endif

Nodeから見える関数の宣言

初期化関数の宣言部分のみが異なります。

lazurite_wrap.cc
#ifdef V8_VER_0
static void Init(Handle<Object> target) {
#endif
#ifdef V8_VER_5
static void Init(Local<Object> target) {
    target->GetIsolate();
#endif

    NODE_SET_METHOD(target, "dlopen", dlopen);
    NODE_SET_METHOD(target, "init", init);
    ..... 省略 .....
    NODE_SET_METHOD(target, "remove", remove);
    NODE_SET_METHOD(target, "dlclose", dlclose);
}

NODE_MODULE(lazurite_wrap, Init)
4
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
7