Passing data between VM and native

175 views
Skip to first unread message

Stuart Adamson

unread,
Jun 26, 2009, 11:02:49 AM6/26/09
to android-ndk
Whats the fastest way of moving a sizable block of data (say 200k)
between the VM and native code. I figure using a byte array there
should be no real overhead other than locking it from the Gc?

Doug Schaefer

unread,
Jun 26, 2009, 12:13:37 PM6/26/09
to andro...@googlegroups.com
A DirectByteBuffer might be better. The data is stored in a native array and you should be able to get a pointer to that array. That's how the OpenGL ES APIs pass vertex arrays around.

fadden

unread,
Jun 26, 2009, 3:56:41 PM6/26/09
to android-ndk
You have a few options:

(1) Declare it as a byte[] in Java source, and pass it into JNI.

This is useful if you want fast access from Java sources. From native
code you can use GetByteArrayElements, but that either has to pin the
array contents or make a copy (which would be really awful for
200KB). GetPrimitiveArrayCritical tries harder to avoid copying, but
it's not guaranteed, and you can't hold the data for long. If you
only need small pieces you can use GetByteArrayRegion to copy parts in
and out.

(2) Allocate it with malloc/new in native code.

This allows you to run flat out in native code, but you can't directly
access the data from Java source code. You can provide some native
methods that allow access to the data if you only need it in pieces
from that side.

(3) Use ByteBuffer.allocateDirect() to get a mix of the two.

As another poster mentioned, you can use this to get native storage
that is accessible from Java. You have to access it through the
ByteBuffer calls, but if you're using this as an I/O buffer it can be
convenient. JNI provides a few calls (NewDirectByteBuffer,
GetDirectBufferAddress, GetDirectBufferCapacity) that make using them
a bit more easier from native code. (This is essentially the same as
#2, but using java.nio interfaces instead of custom calls.)
Reply all
Reply to author
Forward
0 new messages