プリミティブな値を引数で受けとる場合よりもやや面倒。JavaScriptの仕様上どんな値や型でも受けとってしまうので、C++側のチェックコードがどんどん増えていく。
動作確認用のコードがこうだとする
モジュールのコードはこんな感じ
実行結果
動作確認用のコードがこうだとする
1 2 3 4 5 6 7 8 | var Test1 = require( './build/Release/Test1' ); Test1.giveMeObject({ option1: 'This is config option!!' , option2: true }); Test1.giveMeArray([1,2,3,4,5,6]); |
モジュールのコードはこんな感じ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | #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