Passing a multidimensional array to the C++ addon

1,790 views
Skip to first unread message

ec.developer

unread,
Oct 11, 2010, 5:50:58 AM10/11/10
to nodejs
I have to pass an array from my nodejs server script to the C++
addon.
I have created the skeleton of addon, have created the function which
should work with my array.
I pass the JS array to this function, but I don't know how to work
with it in my addon. I receive it using Arguments in my function:

Handle<Value> Func(const Arguments &args)
{
// I just convert it to Object
Local<Object> arg = args[0]->ToObject();
}

How can I convert the object to an array? And how can I access array
elements using the arg?

Thanks.

Oleg "Sannis" Efimov

unread,
Oct 11, 2010, 6:52:01 AM10/11/10
to nodejs
Here is example code from node source:
http://github.com/ry/node/blob/2944e03/src/node_child_process.cc#L92-104

Also you can look at v8::Array API in v8.h, it is simple stupid.

Ben Noordhuis

unread,
Oct 11, 2010, 7:05:15 AM10/11/10
to nod...@googlegroups.com
On Mon, Oct 11, 2010 at 12:52, Oleg "Sannis" Efimov <efim...@gmail.com> wrote:
> Here is example code from node source:
> http://github.com/ry/node/blob/2944e03/src/node_child_process.cc#L92-104

Damn you, Oleg, stealing my thunder. I'd just typed my reply when yours came in!

You can check with args[0]->IsArray() if the argument is really an
array, then cast it with:

Local<Array> a = Array::Cast(*arg[0]);
printf("Array length: %d\n", a.Length());

ec.developer

unread,
Oct 11, 2010, 8:07:37 AM10/11/10
to nodejs
Great! Thanks for linking me to an example :)

ec.developer

unread,
Oct 11, 2010, 12:38:00 PM10/11/10
to nodejs
But what about multidimensional arrays?
For example when I pass an JS array such as:

var arr = new Array();
arr[0] = new Array();
arr[0][0] = 1;
arr[0][1] = 2;
arr[1] = new Array();
arr[1][0] = 3;
arr[1][1] = 4;

And when I try to extract data using this code:
Local<Array> argv_handle = Array::Cast(*args[1]);

for (int i = 0; i < argv_handle->Length(); i++)
{
String::Utf8Value arg(argv_handle->Get(Integer::New(i))-
>ToString());
file << *arg << " | ";
}
I got in my file:
1,2 | 3,4

Sure I can parse each element such as "1,2", splitting this string by
',' , but I'd like to find more natural method to create a regular C++
array based on JS array.
Any hints?

Ben Noordhuis

unread,
Oct 11, 2010, 2:53:51 PM10/11/10
to nod...@googlegroups.com
On Mon, Oct 11, 2010 at 18:38, ec.developer <ec.dev...@gmail.com> wrote:
>    Local<Array> argv_handle = Array::Cast(*args[1]);
>
>    for (int i = 0; i < argv_handle->Length(); i++)
>    {
>        String::Utf8Value arg(argv_handle->Get(Integer::New(i))-
>>ToString());
>        file << *arg << " | ";
>    }

You need to apply the IsArray() check + cast inside the loop.

if (args[0]->IsArray()) {
Local<Array> a = Array::Cast(*args[0]);
for (int index = 0, size = a->Length(); index < size; index++) {
Local<Value> element = a->Get(index);
if (element->IsArray()) {
Local<Array> b = Array::Cast(*element);
// do useful stuff with b
}
}
}

ec.developer

unread,
Oct 12, 2010, 8:03:29 AM10/12/10
to nodejs
That works for me,
Thanks

On Oct 11, 9:53 pm, Ben Noordhuis <i...@bnoordhuis.nl> wrote:
Reply all
Reply to author
Forward
0 new messages