Friday, May 14, 2010

Pointers in JNI / C++

When writing native code for Java (JNI), It's a common behaviour to store the pointer as long in a field in Java, and do a type-cast conversion on the native code back to the original pointer.


I did that on the native module on HornetQ, however this seems to eventually fail.

when using different bit sets as the target compilation (32 bits for instance) this seems to fail when you move back and forth.


The best way for that would be to use a Native Byte Buffer. This way you don't need to worry about conversions. You can just use a pointer back and forth:


Example:


In your Java class, you create this signature:

public class SomeClass
{
public native ByteBuffer initPointer();
}


And in your C++ code:


JNIEXPORT jobject JNICALL Java_SomeClass_initPointer
(JNIEnv * env, jobject obj)
{
return env->NewDirectByteBuffer(myPointer, 0); // size = 0, you don't want anyone to change it
}




Later, any C++ code can get back the pointer by doing:


return (MyClass *) env->GetDirectBufferAddress(myPointer);




I know the word pointer makes this a bit sour, but maybe it will be helpful to someone some day :-)