How to pass a wrapped C++ object to a Javascript callback?
c++, node.js, v8
Solution
You are almost there. You don't need to pass `Arguments` to `Group::Instantiate`. Just pass what you need and use the constructor to create the new instance of `Group`. For example:
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));
}
The method `Group::New` does the rest of the construction work.
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();
}
In `File::OpenGroup` you can do this:
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());
}
Problem
I'm trying to write a Node.js module, using C++, that wraps and exposes some classes from libhdf5. I'm currently interested in two classes from libhdf5. The first one is `File`, and it opens an hdf5 file. The second one is `Group`, and it represents groups within that file. You get Group objects from a File object. I've written some code in which I create a `File` object and attempt to get a `Group` from it. I am trying to make my Node.js module as JavaScripty as possible, so I want to return the group using a callback. So, I am trying to code my module so that it's used like this: ``` var hdf5 = require('hdf5'); var file = new hdf5.File('/tmp/example.h5'); file.getGroup('foobar', function (err, group) { console.log(group); }); ``` So, in the C++ code for my `File` wrapper, I'd have a function that maps to the `getGroup` function here, and it'd call the given anonymous function, passing in any errors as well as the new `Group` object wrapper. Given that this sounded to me like what the Node.js documentation shows to be a factory of wrapped objects, I have modeled my `Group` code after the examples there. So, I have my `Group` wrapper coded up, but am stuck trying to instantiate it. I don't know enough yet to know how to stray away from using the v8 `Arguments` class for function parameters. Because of that, I can't seem to be able to pass in some parameters that I need for my v8 persistent constructor function (because I am instantiating this from C++, and not from JS-land).