开发者

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开发者_如何学C; 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!


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?


instead of

env->CallVoidMethod(obj,aMethodId, &rawAudioCopy);

try

env->CallVoidMethod(obj,aMethodId, rawAudioCopy, 0 , 10);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜