JNI Novice question

A

Aaron Fude

Hi,

Is it possible to be in control of allocating your memory for arrays? In
other words, rather than

jintArray tri = inEnv->NewIntArray(10);
jint *thearray = (jint *) (inEnv->GetIntArrayElements(tri, 0));

to do

jint *thearray = new jint[10];
jintArray tri = inEnv->NewIntArray(Use theArray);

Thanks!

Aaron Fude
 
G

Gordon Beaton

Is it possible to be in control of allocating your memory for
arrays?
[...]

jint *thearray = new jint[10];
jintArray tri = inEnv->NewIntArray(Use theArray);

Not exactly like that, but have a look at NewDirectByteBuffer(),
described under "JNI enhancements in 1.4". It lets you create a
ByteBuffer from memory you've allocated using some other mechanism.
Other JNI functions let you retrieve the address and size of the
original buffer:

jobject allocateByteBuffer(JNIEnv *env, jclass this, jint size)
{
void *p;

if ((p = malloc(size))) {
return (*env)->NewDirectByteBuffer(env,p,size);
}
else return NULL;
}

void freeByteBuffer(JNIEnv *env, jclass this, jobject buf)
{
char *p = (*env)->GetDirectBufferAddress(env,buf);
free(p);
}

In Java, you can treat the ByteBuffer as different buffer type, for
example:

ByteBuffer bb = allocateByteBuffer(100); // allocate ByteBuffer
IntBuffer ib = bb.asIntBuffer(); // get IntBuffer view

In theory you should be able to do the following to get an int array
backed by the ByteBuffer you've just allocated, but unfortunately the
array() method is optional and does not seem to be implemented for
ByteBuffers created this way:

if (ib.hasArray()) {
int[] arr = ib.array();
}

Also have a look at java.nio.MappedByteBuffer, which appears to let
you do something similar with sections of a mapped file.

You didn't mention what specific problem you're trying to solve, so it
might be worth pointing out that when you do this:
jint *thearray = (jint *) (inEnv->GetIntArrayElements(tri, 0));

....that you can make modifications to thearray just as you would any
other array of (j)int, and any changes will propagate back to the
original int[] when you later call ReleaseIntArrayElements() (i.e. you
don't need to use SetIntArrayRegion() to write to the int[]).

/gordon
 
A

Aaron Fude

Thank you. Very informative.

Gordon Beaton said:
Is it possible to be in control of allocating your memory for
arrays?
[...]

jint *thearray = new jint[10];
jintArray tri = inEnv->NewIntArray(Use theArray);

Not exactly like that, but have a look at NewDirectByteBuffer(),
described under "JNI enhancements in 1.4". It lets you create a
ByteBuffer from memory you've allocated using some other mechanism.
Other JNI functions let you retrieve the address and size of the
original buffer:

jobject allocateByteBuffer(JNIEnv *env, jclass this, jint size)
{
void *p;

if ((p = malloc(size))) {
return (*env)->NewDirectByteBuffer(env,p,size);
}
else return NULL;
}

void freeByteBuffer(JNIEnv *env, jclass this, jobject buf)
{
char *p = (*env)->GetDirectBufferAddress(env,buf);
free(p);
}

In Java, you can treat the ByteBuffer as different buffer type, for
example:

ByteBuffer bb = allocateByteBuffer(100); // allocate ByteBuffer
IntBuffer ib = bb.asIntBuffer(); // get IntBuffer view

In theory you should be able to do the following to get an int array
backed by the ByteBuffer you've just allocated, but unfortunately the
array() method is optional and does not seem to be implemented for
ByteBuffers created this way:

if (ib.hasArray()) {
int[] arr = ib.array();
}

Also have a look at java.nio.MappedByteBuffer, which appears to let
you do something similar with sections of a mapped file.

You didn't mention what specific problem you're trying to solve, so it
might be worth pointing out that when you do this:
jint *thearray = (jint *) (inEnv->GetIntArrayElements(tri, 0));

...that you can make modifications to thearray just as you would any
other array of (j)int, and any changes will propagate back to the
original int[] when you later call ReleaseIntArrayElements() (i.e. you
don't need to use SetIntArrayRegion() to write to the int[]).

/gordon
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,905
Latest member
Kristy_Poole

Latest Threads

Top