I think the standard way of going about it is to use a long in java to store the pointer, that way your java code will work on both 32bit and 64bit systems. Obviously you need to compile a different C++ .so/.dll for each platform.
So a simple java wrapper for a C++ class with one method will look something like:
class JavaClass
{
private long native_ptr = 0;
private native long createNativeInstance( params );
private native String nativeMethod( params );
private native void destroyNativeInstance( long p_native_ptr );
public JavaClass( params )
{
this.native_ptr = createNativeInstance( params );
}
public String javaMethod( params )
{
nativeMethod( this.native_ptr, params );
}
public void finalize()
{
destroyNativeInstance( this.native_ptr );
}
}
And your C++ wrapper code looks something like this. (I have named the C++ class CppClass
)
JNIEXPORT jlong JNICALL Java_JavaClass_createNativeInstance
( JNIEnv* p_jenv
, jobject p_jthis
, params )
{
// Convert params from Java types to C++ types if required
return (jlong) new CppClass( converted_params );
}
JNIEXPORT void JNICALL Java_JavaClass_destroyNativeInstance
( JNIEnv* p_jenv
, jobject p_jthis
, jlong p_native_ptr )
{
if( p_native_ptr )
delete (CppClass*)p_native_ptr;
}
JNIEXPORT jstring JNICALL Java_JavaClass_nativeMethod
( JNIEnv* p_jenv
, jobject p_jthis
, jlong p_native_ptr
, params
)
{
// Convert params from Java types to C++ types if required
std::string cpp_result = ((CppClass*)p_native_ptr)->cppMethod( converted_params );
jstring java_result = p_jenv->NewStringUTF( cppResult.c_str() );
return java_result;
// NOTE: std::string destructor will free cpp_result memory
}