10

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

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

我编写了一些代码,在其中创建了一个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这里的函数的函数,它会调用给定的匿名函数,传入任何错误以及新的Group对象包装器。

鉴于这对我来说听起来像是 Node.js 文档显示的包装对象工厂,我已经Group按照那里的示例对我的代码进行了建模。

所以,我已经Group编写了我的包装器,但我一直试图实例化它。我还不够了解如何避免使用 v8Arguments类作为函数参数。因此,我似乎无法传递我的 v8 持久构造函数所需的一些参数(因为我是从 C++ 实例化它,而不是从 JS-land 实例化它)。

4

1 回答 1

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());
}
于 2012-04-27T05:32:02.397 回答