Accessing direct buffer allocated on native side

2,408 views
Skip to first unread message

learner

unread,
Feb 22, 2012, 7:44:31 PM2/22/12
to android-ndk
Hello All,

I am new to JNI and struggling to implement one requirement. I have
allocated direct buffer in JNI using NewDirectByteBuffer() API and
want to access the buffer on Java side. But the ByteBuffer.hasArray()
always returns UnSupportedOperationException.

My requirement: Access the buffer allocated by native in java by not
copying it.

My JNI code looks like this:

static jobject nativeGetByteBuffer(JNIEnv* env, jobject this)
{
Char *gElement = gNative->getByteBuffer(size);//gNative is an instance
of my CPP class where i am returning char*
LOGE("After get bytebuffer call address %d, size %d",gElement, size);
LOGE("size of array is=%d ", (int)size);
myByteBuffer = env->NewDirectByteBuffer((void*)gElement, (jlong)size);
return myByteBuffer;
}

In Java my code is:

ByteBuffer myBuffer = (ByteBuffer)nativeGetByteBuffer();
now accessing myBuffer.hasArray(), myBuffer.array() throws
UnSupportedOperationException.

Please help me in resolving this problem.

Olivier Guilyardi

unread,
Feb 23, 2012, 10:21:36 AM2/23/12
to andro...@googlegroups.com
Hello,

Le 02/23/2012 01:44 AM, learner a �crit :


> Hello All,
>
> I am new to JNI and struggling to implement one requirement. I have
> allocated direct buffer in JNI using NewDirectByteBuffer() API and
> want to access the buffer on Java side. But the ByteBuffer.hasArray()
> always returns UnSupportedOperationException.

That's the point with natively allocated direct buffers, the underlying
storage is opaque from Java. You need to use methods like get() and
put() to access the data .

> My requirement: Access the buffer allocated by native in java by not
> copying it.

You might consider using a normal Java array. The third argument of
get<Type>ArrayElements() allows you to determine whether a copy occurs.
In my tests it was always false.

--
Olivier

Glenn Kasten

unread,
Feb 23, 2012, 10:27:32 AM2/23/12
to android-ndk
The generic documentation for ByteBuffer.array() says this is an
optional operation.
In Honeycomb (Android 3.0) and later, array()
is supported if the object was allocated within managed code by
ByteBuffer.allocateDirect() but is
not supported if the object was allocated using JNI
NewDirectByteBuffer.
Pre-Honeycomb, array() is not supported for either case.

Narayan Kamath

unread,
Feb 23, 2012, 4:33:39 AM2/23/12
to andro...@googlegroups.com
I believe that is expected behaviour for a ByteBuffer that wraps memory that is
not managed by the VM (allocated by your library)

Try using one of the ByteBuffer.get( ) variants to read stuff from your ByteBuffer perhaps ?
That should work.



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




--
_________________
Save Rainforests

learner

unread,
Feb 23, 2012, 11:50:36 AM2/23/12
to android-ndk
Hello Olivier

Thank you for your reply. I will try using .get() method on
ByteBuffer as suggested by you.

But withrespect to your second suggestion of using
get<Type>ArrayElements(), i understand that this method is used on
native side to read the java array.

But my requirement is to create a jbyteArray out of the char* (pointer
to a char array) returned by my cpp code. Currently i am doing byte
by byte copy by running a loop for the size of the char array. I want
to avoid this overhead. Please suggest me any alternative to achieve
this.

regards,

Sriram.

On Feb 24, 12:21 am, Olivier Guilyardi <olivier.guilya...@gmail.com>
wrote:

learner

unread,
Feb 23, 2012, 11:55:42 AM2/23/12
to android-ndk
Thank you Kamath for the suggestion. I will definitely give a try.
> Save Rainforests- Hide quoted text -
>
> - Show quoted text -

sriram sarma

unread,
Feb 23, 2012, 12:23:51 PM2/23/12
to andro...@googlegroups.com

Thank you Glenn i will try thi get method suggested by other experts

learner

unread,
Feb 23, 2012, 7:38:15 PM2/23/12
to android-ndk
Hi Oliver and Narayan,

Thanks for your suggestions. My long lasting trouble has been
resolved. ByteBuffer.get() operation is working for me.

regards,

Sriram.

On Feb 24, 2:23 am, sriram sarma <sriramb...@gmail.com> wrote:
> Thank you Glenn i will try thi get method suggested by other experts
Reply all
Reply to author
Forward
0 new messages