Wednesday, May 26, 2010

Re: Java array handling in JSNI

On 26 mai, 15:34, Alan Chaney <a...@mechnicality.com> wrote:
> Hi
>
> I'm using GWT 2.0.3
>
> It seems to me that in hosted mode when I attempt to use (for example) a
> float[] as a parameter to a native call it silently fails.
>
> The documentation only refers very obliquely to this:
>
> Although Java arrays are not directly usable in JavaScript, there are
> some helper classes that efficiently achieve a similar effect: JsArray
> <http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/com/google/g...>,
> JsArrayBoolean
> <http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/com/google/g...>,
> JsArrayInteger
> <http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/com/google/g...>,
> JsArrayNumber
> <http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/com/google/g...>,
> and JsArrayString
> <http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/com/google/g...>.
> These classes are wrappers around a native JavaScript array.
>
> And, in fact, this appears to be true. If you want an array of floats,
> you must create them in a native method.
>
> As an example, if you create a client function
>
> public void myFunc(int x, int y, float[] z) {
>     do something with z here.
>
> }
>
> "z" will always be 'undefined' in hosted mode (although, oddly, it seems
> that it can work in production mode.)
>
> What does seem to work in both hosted and production mode is:
>
> public static native JsArrayNumber getNativeArray () /*-{ return [ 0, 1,
> -5, -1, -1, -5, 1, -1, -5];    }-*/;
>
> public void myFunc2(int x, int y,  JsArrayNumber z) {
>     // now if invoked something like myFunc2(5, 10, getNativeArray())
> the array works as expected.
>
> }
>
> So, my questions are:
>
> 1. Is what I've just said correct?

If I correctly understood what you said, then yes.

> 2. If so, why doesn't the debug runtime system generate a warning  when
> encountering a 'float []' in hosted mode? Ok it crashes with an obscure
> exception,
> but that isn't very helpful.

Because you can pass a float[] to JSNI, just not use it as an array
from the JSNI code (but you can pass it back to the Java world: the
function returns it, and/or passes it as an argument to a Java method
call)

> If you need to initialize a float [] from a client side java program and
> then pass that array to a native method, you have to do something like:
>
> float [] floats = myinstance.myMethod2CreateFloatArray();
>
> public static native JsArrayNumber createNew() /*-{ return new Array();
>
> }-*/;

There's JavaScriptObject.createArray().<JsArrayNumber>cast() for that.

>     public static JsArrayNumber initArray(float [] f) {
>         JsArrayNumber a = createNew();
>         for (float fv :f)
>             a.push(fv);
>         return a;
>
>     };
>
> This seems to work in both hosted and production mode. Any suggestions
> as to a better way to do this would be appreciated.

Have a look at my JsCollections module, it has utility methods that
will copy the array in DevMode but just pass it as-is when compiled,
so it has no overhead.
http://code.google.com/p/gwt-in-the-air/
> I think the documentation should be a little bit more explicit about
> this, I'd be happy to contribute.
>
> Regards
>
> Alan

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-web-toolkit@googlegroups.com.
To unsubscribe from this group, send email to google-web-toolkit+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

No comments:

Post a Comment