Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JNI Stream binary data from C++ to Java

I need help passing binary data into Java. I'm trying to use jbytearray but when the data gets into Java it appears corrupt. Can somebody give me a hand?

Here's a snip of some example code. First the native C++ side:

printf("Building audio array copy\n");
jbyteArray rawAudioCopy = env->NewByteArray(10);
jbyte toCopy[10];
printf("Filling audio array copy\n");
char theBytes[10] = {0,1,2,3,4,5,6,7,8,9};
for (int i = 0; i < sizeof(theBytes); i++) {
    toCopy[i] = theBytes[i];
}


env->SetByteArrayRegion(rawAudioCopy,0,10,toCopy);
printf("Finding object callback\n");
jmethodID aMethodId = env->GetMethodID(env->GetObjectClass(obj),"handleAudio","([B)V");
if(0==aMethodId) throw MyRuntimeException("Method not found error",99);
printf("Invoking the callback\n");
env->CallVoidMethod(obj,aMethodId, &rawAudioCopy);

and then the Java callback method:

public void handleAudio(byte[] audio){
    System.out.println("Audio supplied to Java [" + audio.length + "] bytes");
    byte[] expectedAudio = {0,1,2,3,4,5,6,7,8,9};
    for (int i = 0; i < audio.length; i++) {
        if(audio[i]!= expectedAudio[i])
            System.err.println("Expected byte " + expectedAudio[i]
                    + " at byte " + i + " but got byte " + audio[i]);
        else System.out.print('.');
    }
    System.out.println("Audio passed back accordingly!");
}

I get the following output when the callback is invoked:

library loaded!
Audio supplied to Java [-2019659176] bytes
Audio passed back accordingly!
like image 621
Cliff Avatar asked Apr 15 '10 20:04

Cliff


People also ask

What is JNI libs?

JNI is the Java Native Interface. It defines a way for the bytecode that Android compiles from managed code (written in the Java or Kotlin programming languages) to interact with native code (written in C/C++).

What is JNI H?

jni. h is a C/C++ header file included with the JDK that maps Java types to their native counterparts. javah automatically includes this file in the application header files.

What is Java native library?

Native libraries are platform-specific library files, including . dll, . so, or *SRVPGM objects, that can be configured within shared libraries. Native libraries are visible to an application class loader whenever the shared library is associated with an application.


1 Answers

After fixing my above mistake I'm now looking for the most efficient way of copying raw byte arrays back into Java. What I have above seems a little less than ideal since I'm planning on supporting a high number of repeat copies. I experimented with passing the char array directly to the setByteArrayRegion call which appears to work in this simple case but I'm wondering if I need to perform pinning. How is that done when you create new arrays on the native side? Do I just call getByteArrayRegion with a FALSE after the set? Can I un-pin after the call into Java completes? Are there online examples of high performance raw binary data shuttling back to java that I can learn from?

like image 74
Cliff Avatar answered Oct 30 '22 22:10

Cliff