2012-04-26 2 views
10

맨발로 설명해 드리겠습니다.래핑 된 C++ 객체를 Javascript 콜백에 전달하는 방법은 무엇입니까?

저는 C++을 사용하여 Node.js 모듈을 작성하려고합니다.이 모듈은 libhdf5의 일부 클래스를 래핑하고 노출합니다.

저는 현재 libhdf5의 두 클래스에 관심이 있습니다. 첫 번째 파일은 File이고 hdf5 파일이 열립니다. 두 번째 파일은 Group이며 해당 파일 내의 그룹을 나타냅니다. File 객체에서 Group 객체를 가져옵니다.

File 개체를 만들고 Group을 가져 오는 코드를 작성했습니다. 가능한 한 Javascripty로 Node.js 모듈을 만들려고하므로 콜백을 사용하여 그룹을 반환하고 싶습니다. 그것을

var hdf5 = require('hdf5'); 
var file = new hdf5.File('/tmp/example.h5'); 
file.getGroup('foobar', function (err, group) { console.log(group); }); 

그래서, C++ 코드 내 File 래퍼 내가 여기 getGroup 기능에 매핑하는 기능이있을 것이다, 그리고 : 그래서, 나는 그것이 이런 식으로 사용되는 있도록 내 모듈을 코딩하는 것을 시도하고있다 주어진 익명 함수를 호출하여 오류를 전달하고 새로운 Group 객체 래퍼를 전달합니다.

Node.js 설명서에 표시된 내용이 factory of wrapped objects 인 것처럼 나에게 들었을 때, 나는 그 곳의 예제 다음에 Group 코드를 모델링했습니다.

따라서 Group 랩퍼가 코딩되었지만이를 인스턴스화하려고 시도하지 않았습니다. 함수 매개 변수에 대해 v8 Arguments 클래스를 사용하는 것을 배제하는 방법을 아직 충분히 알지 못합니다. 그렇기 때문에 v8 Persistent 생성자 함수에 필요한 매개 변수를 전달할 수없는 것 같습니다 (JS-land가 아닌 C++에서 인스턴스를 생성하기 때문에).

누군가 제발 my code for libhdf5을보고 나에게 이것을 달성하는 방법에 대한 포인터를 주시겠습니까? 나는 거의 내가 거기에있는 것처럼 느낀다. 그러나 나는 단지 무엇인가 놓치고있다. https://github.com/ryancole/node-hdf5/blob/master/src/h5_group.cc#L57-72 여기

내가 내 매개 변수를 전달해야 할 경우 라인 인수로 강조 표시된과 함께, 내 File 래퍼 (또는 무엇이든 그것이 내가 필요가있다 : 생성자 함수가 강조 표시 여기

Group 래퍼 이 작업을하기로 변경 : https://github.com/ryancole/node-hdf5/blob/master/src/h5_file.cc#L110

미리 감사드립니다, 감사를 텍스트의 벽을 읽는 :)

답변

9

당신은 거의있다.. ArgumentsGroup::Instantiate에 전달할 필요가 없습니다. 필요한 것을 전달하고 생성자를 사용하여 Group의 새 인스턴스를 만듭니다. 예 :

Handle<Value> Group::Instantiate(const std::string& name) { 
    HandleScope scope; 

    Local<v8::Value> argv[1] = { 
     Local<v8::Value>::New(String::New(name.c_str())) 
    }; 

    return scope.Close(Constructor->NewInstance(1, argv)); 
} 

Group::New은 나머지 작업을 수행합니다.

Handle<Value> Group::New(const Arguments& args) { 
    HandleScope scope; 

    if (!args[0]->IsString()) { 
     return ThrowException(Exception::TypeError(String::New("First argument must be a string"))); 
    } 
    const std::string name(*(String::Utf8Value(args[0]->ToString()))); 
    Group * const group = new Group(name); 
    bar->Wrap(args.This()); 

    return args.This(); 
} 

File::OpenGroup에서이 작업을 수행 할 수 있습니다

Handle<Value> File::OpenGroup (const Arguments& args) { 
    HandleScope scope; 

    if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsFunction()) { 
     ThrowException(Exception::SyntaxError(String::New("expected name, callback"))); 
     return scope.Close(Undefined()); 
    } 
    const std::string name(*(String::Utf8Value(args[0]->ToString()))); 
    Local<Function> callback = Local<Function>::Cast(args[1]); 

    const unsigned argc = 2; 
    Local<Value> argv[argc] = { 
     Local<Value>::New(Null()), 
     Local<Value>::New(Group::Instantiate(name)) 
    }; 
    callback->Call(Context::GetCurrent()->Global(), argc, argv); 

    return scope.Close(Undefined()); 
} 

HTH 것은

+0

그건 당신이 다른 클래스의 인스턴스를 반환하는 팩토리 메소드 ('그룹 : Instantiate')을해야한다는 말을하는 것입니다 ? – ZachB

관련 문제