简体   繁体   中英

How to send Java ByteBuffer to C using JNI?

Firstly, I want to say that the old answers doesn't work (for example, GetDirectBufferAddress function in below answers want one parameter now) at the moment as here:

JNI - native method with ByteBuffer parameter

and here,

how to write and read from bytebuffer passing from java to jni

It would be better if someone helps..

So, I can't send correctly my ByteBuffer, which's some elements filled, to C from Java using JNI and I can't return that ByteBuffer's elements again to C

My native function decleration:

public native int myfunc(ByteBuffer pkt);

Allocation for it

private ByteBuffer pkt = ByteBuffer.allocate(1000);

I am calling it in this way:

System.out.println(myfunc(pkt));  // Doesn't works, throws exception
pkt.position(0);
System.out.println(pkt.get()); // works, when I do comment line above .println

And my C codes as below:

JNIEXPORT jint JNICALL Java_xxx_myfunc(JNIEnv *, jobject, jobject); // header


JNIEXPORT jint JNICALL Java_xxx_myfunc(JNIEnv *env, jobject obj, jobject pkt) // function
{
  jbyte *buff = (jbyte *) env->GetDirectBufferAddress(pkt);
  // buff[0] = 0; I've also tried in this way
  return buff[0];
  //return 1; if I return 1, it returns correctly
}

when I run the java program it throws exception. How can I return my filled ByteBuffer values from C?

EDIT

A fatal error has been detected by the Java Runtime Environment:
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x719c16b8, pid=1096, tid=1900

To use GetDirectBufferAddress() you must guarantee that pkt is direct (you can check this with isDirect() ). The easy way to obtain such object is ByteBuffer.allocateDirect() . Direct ByteBuffer can be created from C++, too.

The difference between direct and indirect ByteBuffer is clearly explained in the Java oficial doc .

Update I see your update. No, ByteBuffer.allocate(1000) does not produce a DirectByteBuffer.

As @Tom Blodget correctly noted , the JNI spec explicitly says that GetDirectBufferAddress() can return NULL. This works both ways: the call itself should not crash if pkt is an indirect ByteBuffer, but you must check the result even if you are sure that pkt is a DirectByteBuffer.

You can't use GetDirectBufferAddress() except on a direct byte buffer. You don't have a direct byte buffer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM