2012-04-26 65 views
10

我跟我解釋這一點。如何將封裝的C++對象傳遞給Javascript回調?

我想寫一個Node.js的模塊,採用C++,它包裝和libhdf5暴露了一些課程。

我從libhdf5在兩個班目前有興趣。第一個是File,它打開一個hdf5文件。第二個是Group,它代表該文件中的組。您從File對象獲取組對象。

我寫了一些代碼,我在其中創建了一個File對象並試圖從中獲取Group。我試圖讓我的Node.js模塊儘可能的Javascripty,所以我想使用回調返回組。所以,我試圖代碼我的模塊,這樣它的使用是這樣的:

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

因此,在C++代碼爲我File的包裝,我不得不在這裏映射到getGroup功能的功能,它'd調用給定的匿名函數,傳遞任何錯誤以及新的對象包裝器。

鑑於這聽起來像是什麼Node.js文檔顯示爲factory of wrapped objects,我已經模擬了我的Group代碼後的例子。

所以,我有我的Group包裝編碼,但我堅持努力實例化。我還不知道如何遠離使用v8 Arguments類來獲取函數參數。正因爲如此,我似乎無法能夠在某些參數,我需要爲我的V8持久的構造函數傳遞(因爲我是從C++實例化這一點,而不是從JS-土地)。

會有人請看看my code for libhdf5,並給我一個指針就如何實現這一目標?我覺得我快到了,但我只是想念一些東西。

這裏是我的Group的包裝,具有構造函數強調:https://github.com/ryancole/node-hdf5/blob/master/src/h5_group.cc#L57-72

這裏是我的File的包裝,用線在突出顯示在那裏我需要在我的參數傳遞,作爲參數(或不管它是什麼,我需要更改爲這個工作:提前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 2015-07-30 02:09:37