2016-09-01 1 views
1

v8でC++クラスメンバーを公開したいが、クラスメソッドを公開する方法はわかっているが、クラスメンバーを公開する方法はわからない。V8でC++クラスメンバーを公開する方法

C++クラス:

class Person{ 
public: 
string name; 
} 

Javascriptを:

var p1 = new Person(); 
p1.name = "Jack"; 

私はこれを達成したい、それは可能ということです。ありがとう!

+0

多分、cctest/test-api.ccヘルプの例です。たとえば、getRealNamedProperty()を使用してプロパティ名を取得できます。 – user835611

答えて

3

PersonプロトタイプテンプレートにSetAccessor()を使用して、そのメンバーに外部V8データとしてポインタを渡すことができます。しかし、PersonのC++インスタンスをV8オブジェクトにラップしてから、このV8オブジェクトをC++オブジェクトに戻して、アクセッサのgetter/setterコールバックをargsから取り除く必要があります。

私はv8ppライブラリでこの方法を使用します。このライブラリは、V8へのC++クラスと関数の公開を簡素化します。クラスのメンバ変数の場合、それは次のようになります。

v8pp::class_<Person> Person_class(isolate); Person_class // bind member variable .set("name", &Person::name)

0

正しいのですが、もう少し拡大して、あなたがInternalFieldCount = 1とスローで(おそらくFunctionTemplate経由)ObjectTemplateを作成すると述べた何PMED v8 :: Externalとしてcppオブジェクトがそこにあります。

次に、データメンバに対応したいjavascriptプロパティの名前(JavaScriptの予約語に注意する必要がありますが、同じ名前の可能性があります)と取得する関数を使用して、ObjectTemplateでSetAccessorを呼び出します。それ。その関数では、内部フィールドからcppオブジェクトを取得し、それを使用してデータメンバーの値を返し、必要な形式でjavascriptに戻します。

次に、ObjectTemplateを使用してオブジェクト(ObjectTemplate::NewInstance())を作成すると、適切なcppオブジェクトをv8::Object::SetInternalField()呼び出しで内部フィールドに配置する必要があります。

次のコードがテストされていませんが、それはかなり近いはず:

void getter_function(Local<String> property, const PropertyCallbackInfo<Value> &info) { 
    Person * person = static_cast<Person*>(info.This().GetInternalField(0)); 
    info.GetReturnValue().Set(v8::String::NewFromUtf8(person->name.c_str())); 
} 
auto obj_template = v8::ObjectTemplate::New(a_v8_isolate); 
obj_template.SetAccessor(v8::String::NewFromUtf8(a_v8_isolate, "name"), getter_function /* setter is optional */); 
auto js_obj = my_object_template.NewInstance(a_v8_context); 
js_obj.SetInternalField(new Person()); 

私は、あまりにも、これを実行するためのライブラリを書かれている:https://github.com/xaxxon/v8toolkitしかしPMEDのは、おそらく、より安定しています。あなたのソースコードを自動的に読んでC++クラスのためのバインディングを自動的に生成するclang C++コンパイラ用のプラグインのような、私の中にはちょっとした狂気のものがあります。

関連する問題