プリミティブな値を引数で受けとる場合よりもやや面倒。JavaScriptの仕様上どんな値や型でも受けとってしまうので、C++側のチェックコードがどんどん増えていく。
動作確認用のコードがこうだとする
モジュールのコードはこんな感じ
実行結果
動作確認用のコードがこうだとする
var Test1 = require('./build/Release/Test1');
Test1.giveMeObject({
option1: 'This is config option!!',
option2: true
});
Test1.giveMeArray([1,2,3,4,5,6]);
モジュールのコードはこんな感じ
#include <node.h>
#include <v8.h>
#include <iostream>
using namespace v8;
Handle<Value> HandleObjectMethod(const Arguments& args) {
HandleScope scope;
// 第一引数の型がObjectかどうかをチェック
if (!args[0]->IsObject()) {
Local<String> msg = String::New("Argument must be Object type");
ThrowException(Exception::TypeError(msg));
return scope.Close(Undefined());
}
// v8::Object型にキャスト
Local<Object> obj = Local<Object>::Cast(args[0]);
std::string strOption1 = "";
bool bOption2 = "";
{
// Check Option1
Local<Value> v = obj->Get(String::New("option1"));
if (v.IsEmpty() || !v->IsString()) {
Local<String> msg = String::New("Option1 is not specified or invalid type");
ThrowException(Exception::TypeError(msg));
return scope.Close(Undefined());
} else {
int length = v->ToString()->Length();
char c[length];
v->ToString()->WriteAscii(c);
strOption1 += c;
}
}
std::cout << "Option1 = " << strOption1 << std::endl;
{
// Check Option2
Local<Value> v = obj->Get(String::New("option2"));
if (v.IsEmpty() || !v->IsBoolean()) {
Local<String> msg = String::New("Option2 is not specified or invalid type");
ThrowException(Exception::TypeError(msg));
return scope.Close(Undefined());
} else {
bOption2 = v->ToBoolean()->Value();
}
}
std::cout << "Option2 = " << bOption2 << std::endl;
return scope.Close(Boolean::New(true));
}
Handle<Value> HandleArrayMethod(const Arguments& args) {
HandleScope scope;
// 第一引数の型がArrayかどうかのチェック
if (!args[0]->IsArray()) {
Local<String> msg = String::New("Argument must be Array type");
ThrowException(Exception::TypeError(msg));
return scope.Close(Undefined());
}
// v8::Arrayにキャスト
Local<Array> arr = Local<Array>::Cast(args[0]);
int length = arr->Length();
std::cout << "Length:" << length << std::endl;
for (int i = 0; i < length; i++) {
// Arrayの各要素にアクセス
Local<Value> v = arr->Get(i);
// Something todo
}
return scope.Close(v8::Boolean::New(true));
}
void init(Handle<Object> target) {
// メソッドのexport
target->Set(String::NewSymbol("giveMeObject"), FunctionTemplate::New(HandleObjectMethod)->GetFunction());
target->Set(String::NewSymbol("giveMeArray"), FunctionTemplate::New(HandleArrayMethod)->GetFunction());
}
NODE_MODULE(Test1, init)
実行結果
Option1 = This is config option!! Option2 = 1 Length:6