本サイトでは、アフィリエイト広告およびGoogleアドセンスを利用しています。

JavaScriptをC++からのスクリプトとして使う(クラス編)

C++で定義してあるクラスをJavaScript側で使いたいことがあります。今回はその説明をしてJavaScript編を終了にしたいと思います。

[javascript]
var hoge = new Point(1,2);
hoge.x = 100;
hoge.y = 250;
var foo = new Point;
foo = null;
[/javascript]

こんな感じのJavaScriptを実行させて、C++側にあるPointというクラスを扱うことを考えていきたいと思います。

C++でクラスの定義

[cpp]
class Point {
public:
Point() : _x(0), _y(0) { }
Point( double x, double y ) : _x(x), _y(y) { }

double _x, _y;
};
[/cpp]
このようなクラスを作り、下記に示すようにメンバ変数へのアクセスを許可するための関数を作ります。

[cpp]
v8::Handle GetPointX( v8::Local property, const v8::AccessorInfo& info ) {
using namespace v8;
Local self = info.Holder();
Local wrap = Local::Cast( self->GetInternalField(0) );
void* ptr = wrap->Value();
Point* pPoint = static_cast( ptr );
double val = pPoint->_x;
return v8::Number::New( val );
}
v8::Handle GetPointY( v8::Local property, const v8::AccessorInfo& info ) {
using namespace v8;
Local self = info.Holder();
Local wrap = Local::Cast( self->GetInternalField(0) );
void* ptr = wrap->Value();
Point* pPoint = static_cast( ptr );
double val = pPoint->_y;
return v8::Number::New( val );
}
void SetPointX( v8::Local property, v8::Local value, const v8::AccessorInfo& info ) {
using namespace v8;
Local self = info.Holder();
Local wrap = Local::Cast( self->GetInternalField(0) );
void* ptr = wrap->Value();
static_cast( ptr )->_x = value->NumberValue();
}
void SetPointY( v8::Local property, v8::Local value, const v8::AccessorInfo& info ) {
using namespace v8;
Local self = info.Holder();
Local wrap = Local::Cast( self->GetInternalField(0) );
void* ptr = wrap->Value();
static_cast( ptr )->_y = value->NumberValue();
}
[/cpp]

続いて、Pointクラスを生成・破棄するための関数も用意しておきます。生成時には破棄の時にどの関数で処理させるかを指定させています。

[cpp]
static void Point_Dispose( v8::Persistent handle, void* parameter ) {
Point* pPoint = static_cast( parameter );
printf( “destruct.\n” );
delete pPoint;
handle.Dispose();
}

static v8::Handle Point_Construct( const v8::Arguments& args ) {
using namespace v8;
Point* pPoint = NULL;
if( args.Length() == 2 ) {
double a = args[0]->NumberValue();
double b = args[1]->NumberValue();
pPoint = new Point( a, b );
} else {
pPoint = new Point();
}

printf( “construct.\n” );
Local thisObj = args.This();
thisObj->SetInternalField( 0, External::New( pPoint ) );
Persistent holder = Persistent::New( thisObj );
holder.MakeWeak( pPoint, Point_Dispose );
return thisObj;
}
[/cpp]

ここまででクラスの準備は整ったので、JavaScriptエンジンにこれらの関数群を登録します。
前回の関数の登録のときの処理と割と似ています。

[cpp]
Handle global = ObjectTemplate::New();

Local clazz = FunctionTemplate::New( Point_Construct );
clazz->SetClassName( String::New( “Point” ) );
Local instanceTmpl = clazz->InstanceTemplate();
instanceTmpl->SetInternalFieldCount( 1 );
instanceTmpl->SetAccessor( String::New(“x”), GetPointX, SetPointX );
instanceTmpl->SetAccessor( String::New(“y”), GetPointY, SetPointY );
global->Set( String::New(“Point”), clazz );
[/cpp]

あとはこれを実行させてみることにします。

[cpp]
// JavaScriptソースコードを含む文字列を作ります。
const char* js =
“var hoge = new Point(1,2);\n”
“hoge.x = 100;\n”
“hoge.y = 250;\n”
“var foo = new Point;\n”
“foo = null;\n”
;
Handle source = String::New( js );

// ソースコードをコンパイルします。
Handle

すらりんをフォローする
すらりん日記
タイトルとURLをコピーしました