Making and Returning Java Byte Arrays in C++ via JNI (Help! Please!)

R

res7cxbi

How do you make java byte arrays, fill them with values, and return
them in c++? I have no clue where to start. The JNI Tutorial a at
Java's website isn't much help because it doesn't really explain how to
make new jarrays. Any tips, how-tos and example code are welcome! (And
can anybody please explain me what's jsize? Is it just another integer?)
 
R

res7cxbi

Thanks - this is a huge start for me

how do you fill it with values though...?

Thanks (Again)
 
R

res7cxbi

Let me clarify my last reply...

How do you fill the jbyteArray with values from a BYTE* array (which is
native)?
 
G

Gordon Beaton

How do you fill the jbyteArray with values from a BYTE* array (which
is native)?

Using one of these mechanisms:

- SetByteArrayRegion()

- use GetByteArrayElements(), modify the local copy using "normal"
assignment, then use ReleaseByteArrayElements() to propagate your
changes back to the Java array.

/gordon
 
R

res7cxbi

Thanks guys, it works except for one thing....
The VM crashes!!!

This is the most interesting problem ever encountered.
I've tested each line one by one and after that
I've found out that the lines that are commented out
is the code that is causing the VM to crash

All the other code works perfectly. But the loop that
copies the contents of the buffer retrieved
by GetSample() (a method implemented by me)
into the jbyte array completely screws up everything

More interestingly, this method works for the first 2 invocations
if compiled with the for loop then crashes!

Compile w/o the loop method works perfectly

Im just as confused as you are

That loop is crucial because it is what fills the arrays!
Or is there a workaround?

Here's the code for it... it completely stumped me... any ideas are
highly appreciated!

JNIEXPORT jbyteArray JNICALL Java_SomeClass_readNextArray
(JNIEnv *env, jobject obj)
{
BYTE *buffer = NULL;
DWORD bufferlen = 0;
GetSample(&buffer, &bufferlen);
jbyteArray bArray = env->NewByteArray( bufferlen );
jbyte *jBytes = env->GetByteArrayElements( bArray, 0);
//Problem Code!!!
//for(DWORD i = 0; i < bufferlen; i++) {
// jBytes = buffer;
//}
env->ReleaseByteArrayElements( bArray, jBytes, 0);
return bArray;
}
 
R

res7cxbi

Actually it might be a problem with the GetSample() implementation.
Time to check it out...... keep you guys updated
 
C

Chris Uppal

The VM crashes!!!

Not quite the right way to put it. The correct expression is "My code crashes,
taking the JVM with it!!!".

jbyteArray bArray = env->NewByteArray( bufferlen );
jbyte *jBytes = env->GetByteArrayElements( bArray, 0);

Never omit error-checking in JNI code. NEVER.

Other than that nothing obvious leaps out at me. Possibly the error is
elsewhere in your code. Are you /certain/ that GetSample() works, and returns
the correct values in buffer and bufferlen ? Where does the "buffer" come
from, is it malloc()/new()-ed ? If so then where's the corresponding
free()/delete[] ?

-- chris
 
R

res7cxbi

If this helps, this is the error:

#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x10001640, pid=3212,
tid=3068
#
# Java VM: Java HotSpot(TM) Client VM (1.5.0_04-b05 mixed mode,
sharing)
# Problematic frame:
# C [ArrayReaderTest.dll+0x1640]
#
# An error report file with more information is saved as
hs_err_pid3212.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
 
R

res7cxbi

The "buffer" comes from an INSSBuffer which comes from the
IWMSyncReader in the Windows Media Format SDK. I want to pass samples
to my java app
 
G

Gordon Beaton

Nope... GetSample() is fine

When everything is fine but your code is still crashing, then your
definition of "fine" needs adjusting.

Aside from your neglect to check return values (as Chris already
pointed out) there is nothing inherently wrong with the native code
you posted.

What do buffer and bufferlen contain after calling GetSample()? Are
you sure that the length is correct for the given buffer?

What happens if you completely remove the call to GetSample(), and do
something like this instead (just to test):

BYTE buffer[] = { 1, 2, 3, 4, 5 };
DWORD bufferlen = 5;

/gordon
 
R

res7cxbi

Im running out of time... i'll just set up a buffer in the native code
and have individual elements passed to the java app by native methods
and have a for loop to reconstruct the array... really, can't figure
this out...

Do you guys think there's a performance penalty for java repeatly
asking for the next individual element or is it more favorable passing
the entire array to the java app?
 
R

res7cxbi

works perfectly... hey now that's even more interesting...

the buffer contains PCM audio data as unsigned bytes (i believe)
the buffer is usually somewhere in the 50,000 elements at any one time
 
G

Gordon Beaton

Do you guys think there's a performance penalty for java repeatly
asking for the next individual element or is it more favorable passing
the entire array to the java app?

Crossing the JNI boundary is expensive. Return the whole array!

/gordon
 
G

Gordon Beaton

works perfectly... hey now that's even more interesting...

So I suggest you look more closely at GetSample(). Does bufferlen
agree with buffer? Is the buffer allocated dynamically? If so,
shouldn't you free it at some point?

/gordon
 
G

Gordon Beaton

jbyte *jBytes = env->GetByteArrayElements( bArray, 0);
//Problem Code!!!
//for(DWORD i = 0; i < bufferlen; i++) {
// jBytes = buffer;
//}
env->ReleaseByteArrayElements( bArray, jBytes, 0);



Not that this has anything to do with your problem, but you can
replace all of the above code (two calls to Set/GetByteArrayElements
and the intervening loop) with a single call to SetByteArrayRegion.

As an added bonus, SetByteArrayRegion likely uses a more efficient
mechanism to transfer the data.

/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,766
Messages
2,569,569
Members
45,045
Latest member
DRCM

Latest Threads

Top