2016-08-01 4 views
0

を無効にするには、現在、私は次のように使用して機能を結合しています:V8 - args.Dataキャスティング()バックポインタ

global->Set(String::NewFromUtf8(isolate, "print", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, V8Instance::js_print)); 

機能により:

static void js_print(const v8::FunctionCallbackInfo<v8::Value> &args); 

実装:

void V8Instance::js_print(const v8::FunctionCallbackInfo<v8::Value> &args) { 
    for (int i = 0; i < args.Length(); i++) { 
     v8::HandleScope handle_scope(args.GetIsolate()); 
     v8::String::Utf8Value str(args[i]); 
     std::cout << *str << std::endl; 
    } 
    std::cout << std::endl; 
} 

しかし、私はjs_print関数がV8Instanceクラスのメンバである変数にアクセスできるようにします。 V8には、メンバー関数をバインドできるboost::bind(&Class::function, this, ...)を使用できるようなものがありますか、呼び出されるたびにリファレンス/ポインタで必要な変数をjs_printに渡す方法がありますか?

私はFunctionTemplate::Newのデータパラメータを使用して私のクラスへのポインタを渡すことができることを見出したアップデート

:私はargs.Data()を使用して、私のjs_print機能でこれにアクセスすることができます

Local<External> self = External::New(isolate, (void *) this); 
global->Set(String::NewFromUtf8(isolate, "print", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, V8Instance::js_print, self)); 

が、これはLocal<Value>を返します。どのオブジェクトをvoid *にキャストしてから、私のクラスポインタV8Instance *にキャストするのか分かりません。誰もこれを行う方法を知っていますか?

答えて

1

対応するv8::ObjectTemplateにC++オブジェクトをラップし、V8 Embedder's Guideで説明されているように、そのためのアクセサを設定することができます。

C++クラスをラップする(JavaScriptからこのC++クラスの多くのC++インスタンスを使用する)には、V8内のC++オブジェクトへのポインタを格納するラップされたクラスのJSコンストラクタ関数としてV8 FunctionTemplateを作成する必要がありますObjectインスタンスを作成し、そのクラス内の目的のメンバ関数のV8関数コールバックを設定します。これらのコールバックは、V8オブジェクトからC++オブジェクトをアンラップし、アンラッピングされたオブジェクトに対して適切なメンバ関数を呼び出す必要があります。

このアプローチは、定型コードをたくさん作成することにつながります。 Node.jsはネイティブのアドオンでnode::ObjectWrapのC++クラスを継承することができます。

また、C++のクラス、関数、ラムダを継承なしで非侵入的にバインドするライブラリv8ppを作成しました。

類似のライブラリがいくつかあります。しかし、私が知っているように、彼らは時代遅れであり、新しいV8バージョンをサポートしていません。 外部データからV8Instance*を取得するには、args.Data()の値をv8::Externalにキャストし、その外部値からポインタを取得してV8Instance*にキャストする必要があります。このような何か:

void V8Instance::js_print(const v8::FunctionCallbackInfo<v8::Value> &args) 
{ 
    v8::Local<v8::External> ext = args.Data().As<v8::External>(); 
    V8Instance* self = static_cast<V8Instance*>(ext->Value()); 
    .... 
} 
+0

私はV8のGoogleのグループに尋ねたと明らかに私はちょうど 'FunctionTemplate'のデータとして私のクラスへのポインタを渡すことができ、私が使用してこれを行う方法を考え出した(第3引数)。 ' ' Local self = External :: new(分離、(void *)this); ' そして' self'を3番目の引数として渡しますが、 'args.Data ( 'js_print'の中で)' V8Instance * 'に戻る – Jack

+0

私の答えに更新が追加されました。 – pmed

+0

ありがとう、ええ、それは私が探していたものです。正しいとマークされました – Jack