Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Returning a JS Array to JavaScript from a C++ XPCOM object access through XPConnect

24 views
Skip to first unread message

tradiate

unread,
Feb 22, 2007, 1:56:45 PM2/22/07
to
I have a C++ XPCOM object that I have exposed to JavaScript. Calls
from the JS environment to methods on my C++ object are working fine.
I'm now introducing a new method to my C++ object that needs to return
a JS Array back to the JavaScript caller. Is there an example in the
mozilla tree that demonstrates how to do this sort of thing? If not,
does anyone care to share snippet(s), or point me to a site, that
illustrates the technique?

Boris Zbarsky

unread,
Feb 22, 2007, 2:01:17 PM2/22/07
to
tradiate wrote:
> I have a C++ XPCOM object that I have exposed to JavaScript. Calls
> from the JS environment to methods on my C++ object are working fine.
> I'm now introducing a new method to my C++ object that needs to return
> a JS Array back to the JavaScript caller.

You can't, really. You can use one of the XPCOM array classes, but you can't
return a JS Array.

-Boris

Igor Tandetnik

unread,
Feb 22, 2007, 2:17:00 PM2/22/07
to

// XPIDL
void getArray(out unsigned long count, [array, size_is(count), retval]
out long retv);

// C++
NS_IMETHODIMP MyComponent::GetArray(PRUint32* count, PRInt32** retv) {
*count = 10;
*retv = (PRInt32*)nsMemory::Alloc(*count * sizeof(PRInt32));

for (int i = 0; i < 10; ++i) (*retv)[i] = i;

return NS_OK;
}

// JavaScript
var arr = myComponent.getArray({});

Igor Tandetnik


tradiate

unread,
Feb 22, 2007, 2:19:23 PM2/22/07
to
On Feb 22, 2:01 pm, Boris Zbarsky <bzbar...@mit.edu> wrote:
> You can't, really. You can use one of the XPCOM array classes, but you can't
> return a JS Array.
>
> -Boris

To re-phrase, what I'm interested in doing is having a set of things
that live down in the C++ world exposed to JavaScript as a JavaScript
array object (so JS can iterate through them via foreach, etc. and
then access properties on each item in the array). So, literally
passing back a JS Array isn't necessary, per se. Again, if there are
examples out there in Mozilla that use "one of the XPCOM array
classes" to expose a set of C++ XPCOM objects to JavaScript in an
array, I'd love a pointer, or two. Thanks.

tradiate

unread,
Feb 22, 2007, 5:13:31 PM2/22/07
to
On Feb 22, 2:17 pm, "Igor Tandetnik" <itandet...@mvps.org> wrote:


Thanks, Igor. This is very close to what I need. Is there a way to
set things up so that the JS code doesn't have to be coded as
xxx.getArray({})? I'd like to lose the {} in the parm list, but as
this stands, if I omit the {} in the parm list, I get an XPC exception
about not enough parms being specified. I want my JS API to be
uncluttered.

Igor Tandetnik

unread,
Feb 22, 2007, 5:28:04 PM2/22/07
to
tradiate <trad...@nc.rr.com> wrote:
>> // JavaScript
>> var arr = myComponent.getArray({});
>
> Thanks, Igor. This is very close to what I need. Is there a way to
> set things up so that the JS code doesn't have to be coded as
> xxx.getArray({})? I'd like to lose the {} in the parm list

I'd like to myself, but I don't know of any way to do that. XPConnect
requires that "out count" parameter, and even though the script can
ignore it (it's available via arr.length) it still has to provide the
placeholder for it. Otherwise XPConnect complains about parameter
mismatch.

I'm afraid this is as clean as it gets. An alternative would be
returning something like nsISupportsArray, which is a royal pain for the
script to work with.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


Alex Vincent

unread,
Feb 23, 2007, 3:31:14 AM2/23/07
to
Igor Tandetnik wrote:
> tradiate <trad...@nc.rr.com> wrote:
>>> // JavaScript
>>> var arr = myComponent.getArray({});
>> Thanks, Igor. This is very close to what I need. Is there a way to
>> set things up so that the JS code doesn't have to be coded as
>> xxx.getArray({})? I'd like to lose the {} in the parm list
>
> I'd like to myself, but I don't know of any way to do that. XPConnect
> requires that "out count" parameter, and even though the script can
> ignore it (it's available via arr.length) it still has to provide the
> placeholder for it. Otherwise XPConnect complains about parameter
> mismatch.
>
> I'm afraid this is as clean as it gets. An alternative would be
> returning something like nsISupportsArray, which is a royal pain for the
> script to work with.

There's also nsIArray. I actually document array handling on my XPCOM
Cheat Sheet - which is actually intended as more of a rosetta stone (I
didn't know the term when I wrote it).

jfd...@gmail.com

unread,
Apr 22, 2007, 11:45:39 PM4/22/07
to
On Feb 22, 3:17 pm, "Igor Tandetnik" <itandet...@mvps.org> wrote:

Since one is allocating memory, do I need to nsMemory::Free it? The
return ends up in JS space ... so will the memory be handled
automagically by XPConnect/Glue?

Thx

Christian Biesinger

unread,
Apr 23, 2007, 8:41:37 AM4/23/07
to dev-tec...@lists.mozilla.org
jfd...@gmail.com wrote:
> Since one is allocating memory, do I need to nsMemory::Free it? The
> return ends up in JS space ... so will the memory be handled
> automagically by XPConnect/Glue?

Yes, if JavaScript calls your function, XPConnect will handle the
freeing. (If you wanted to call it from C++, you'd have to do it yourself)

--
All the world's a stage,
And all the men and women merely players:
They have their exits and their entrances;
And one man in his time plays many parts, [...] --W. Shakespeare

jfd...@gmail.com

unread,
Apr 23, 2007, 4:02:20 PM4/23/07
to
On Apr 23, 8:41 am, Christian Biesinger <cbiesin...@web.de> wrote:

> > Since one is allocating memory, do I need to nsMemory::Free it? The
> > return ends up in JS space ... so will the memory be handled
> > automagically by XPConnect/Glue?
>
> Yes, if JavaScript calls your function, XPConnect will handle the
> freeing. (If you wanted to call it from C++, you'd have to do it yourself)
>

Fantastic ... thanks!

0 new messages