如何将包装的C ++对象传递给Javascriptcallback?

和我解释这一点一样。

我正在尝试使用C ++编写一个Node.js模块,它包装并公开libhdf5中的一些类。

我目前对libhdf5的两个类感兴趣。 第一个是File ,它打开一个hdf5文件。 第二个是Group ,代表该文件中的组。 您从File对象获取组对象。

我写了一些代码,我创build了一个File对象,并试图从中获取一个Group 。 我正在尝试使我的Node.js模块尽可能Javascripty,所以我想使用callback返回组。 所以,我试图编写我的模块,以便它的使用是这样的:

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

所以,在我的File包装器的C ++代码中,我有一个映射到getGroup函数的函数,它会调用给定的匿名函数,传入任何错误以及新的Group对象包装器。

鉴于这听起来像是什么Node.js文档显示为包装对象的工厂 ,我已经模拟了我的Group代码后的例子。

所以,我有我的Group包装编码,但坚持试图实例化它。 我还不知道如何偏离使用v8 Arguments类的函数参数。 正因为如此,我似乎无法传递我需要的一些参数,我的v8持久化构造函数(因为我从C ++实例化这个,而不是从JS-land)。

请有人看看我的代码为libhdf5,并给我一个指示,如何实现这一目标? 我觉得我快到了,但是我只是想念一些东西。

这里是我的Group包装,突出构造函数: https : //github.com/ryancole/node-hdf5/blob/master/src/h5_group.cc#L57-72

这里是我的File包装,线高亮在哪里我需要通过我的参数,作为参数(或无论是我需要改变这个工作: https : //github.com/ryancole/node- HDF5 /斑点/主/ SRC / h5_file.cc#L110

在此先感谢,并感谢您阅读此墙的文字。 🙂

你几乎在那里。 您不需要将Arguments传递给Group::Instantiate 。 只要通过你所需要的,并使用构造函数来创buildGroup的新实例。 例如:

 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方法完成了其余的构build工作。

 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