2016-08-01 2 views
0

현재 나는 다음과 같은 사용하여 기능을 결합하고 포인터를 무효화하는 주조 :V8 - args.Data() 다시

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; 
} 
기능으로

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

그러나 js_print 함수가 V8Instance 클래스의 멤버 인 변수에 액세스하도록하고 싶습니다. V8은 회원 함수를 바인드하게 해주는 boost::bind(&Class::function, this, ...)을 사용할 수있는 것과 비슷합니까? 아니면 호출 할 때마다 js_print에 대한 참조/포인터로 필요한 변수를 전달할 수있는 방법이 있습니까?

업데이트

나는 FunctionTemplate::New의 데이터 매개 변수를 사용하여 내 클래스에 대한 포인터를 전달할 수 있다는 것을 발견했다 :

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

내가 args.Data()를 사용하여 내 js_print 기능이 액세스 할 수 있지만이 Local<Value>을 반환 어떤 객체를 void *으로 다시 캐스팅 한 다음 다시 내 클래스 포인터 V8Instance *으로 캐스팅해야하는지 모르겠습니다. 누구든지이 작업을 수행하는 방법을 알고 있습니까?

답변

1

에 설명 된대로 v8::ObjectTemplate에 C++ 개체를 래핑하고 그에 대한 접근자를 설정할 수 있습니다.

C++ 클래스를 랩핑하려면 (즉, JavaScript에서이 C++ 클래스의 많은 C++ 인스턴스를 사용하려면) V8에 C++ 오브젝트에 대한 포인터를 저장할 래핑 된 클래스의 JS 생성자 함수로 V8 FunctionTemplate을 작성해야합니다 Object 인스턴스를 만들고 해당 클래스의 원하는 멤버 함수에 대한 V8 함수 콜백을 설정합니다. 이러한 콜백은 V8 객체에서 C++ 객체를 언 래핑하고 언 래핑 된 객체에 대해 적절한 멤버 함수를 호출해야합니다.

이 접근법은 많은 상용구 코드를 작성합니다. Node.js는 기본 addon에서 node::ObjectWrap의 C++ 클래스를 상속 할 수 있습니다.

또한 C++ 클래스, 함수 및 lambdas를 상속없이 비 관입 방식으로 바인딩하는 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 구글 그룹에 물어 분명히 난 그냥'FunctionTemplate'의 데이터로 내 클래스에 대한 포인터를 전달할 수 있습니다 내가 사용하여이 작업을 수행하는 방법을 알아 냈어요 (3 인수.) '로컬 자기 = 외부 :: 새로운 (분리, (무효 *)이);' 그리고 제 3 인수로'자기'를 전달하지만 어떻게'args.Data()'('js_print'에서)'V8Instance *'로 돌아 가기 – Jack

+0

내 대답에 업데이트가 추가되었습니다. – pmed

+0

고마워, 네가 그걸 찾고있어. 올바른 것으로 표시했습니다. – Jack