snowmantw
snowmantw

Reputation: 1621

How to apply callback with v8::Arguments?

I'm writing a Node.js native module with a function accepting arbitrary length arguments, and it's similar with this in JS:

cb  = function( )
{
  // Receive arguments and do something...
}

foo = function( )
{
  cb.apply({}, arguments)
}

foo([1,2,3])
foo([4])

Here, foo apply the cb with arbitrary arguments.

And the C++ version, according to most Node.js articles about callbacks, would like this:

Handle<Value> Foo(const Arguments& args) 
{
  HandleScope scope;

  // Assume that we can get callback from somewhere else.
  Local<Function> cb = getExistingCallback();  

  // Now call it with arbitrary arguments.
  cb->Call(Object::New(), args.Length(), args.Data());

  return scope.Close(Undefined());
}

But Arguments::Data can only provide v8::Local<v8::Value>&, not v8::Handle<v8::Value>*, so compiler will throw errors.

Because Local derived from Handle, it's not the problem. I just don't if there is any solution I can use to avoid copy all member from the Data to a new array then pass it in.

Upvotes: 1

Views: 1416

Answers (1)

loganfsmyth
loganfsmyth

Reputation: 161657

Arguments::Data is not what you want. That data is totally unrelated to the values passed to the function itself, if you look at the source. Data reads from implicit_args_ while the data you want is in values_.

I don't think there is an easy way to get at that information without using operator[] so maybe your best bet is the construct the list dynamically? You can use a std::vector since its data values are contiguous.

int argc = args.Length();
std::vector<Local<Value>> argv;
for (int i = 0; i < argc; i++){
  argv.push_back(args[i]);
}
cb->Call(Object::New(), argc, &argv[0]);

Upvotes: 1

Related Questions