JNI - how to use multiple Jni wrapper instances with different fields?

痴心易碎 提交于 2019-12-02 02:59:57

You need to have C++ classes on the JNI side, and you need to associate an instance of the C++ class with each instance of your JNI wrapper class. You will need to add native methods to new and delete the C++ class instances, and you will need a bullet-proof way of ensuring that the delete-calling method gets called every time an instance of your JNI wrapper class is released, e.g. via a close() method, finally{} blocks, or even a finalize() method: this is one case where its usage is legitimate. You need to store a pointer to the C++ instance in each Java instance, e.g. as a Java long, and you need to get hold of that on the C++ side and cast it to a C++ class instance to get hold of the per-instance data.

I've found a possible solution (link here), to either use a jlong or jobject to be a handle (or pointer, if you wish) to the object that was created on the JNI side.

people said it's better to use a jobject as ByteBuffer instead of jlong for better compatibility.

the solution is :

Java side:

private native ByteBuffer init();
private native void foo(ByteBuffer handle);

JNI side:

/**a class to hold the fields*/
class FieldsHolder
  {
  ... //private fields, for each instance
  }

creating the JNI object and sending to java side:

JNIEXPORT jobject JNICALL ...init(JNIEnv * env, jobject obj)
  {
  FieldsHolder* myClass= new FieldsHolder();
  ... //prepare fields of the class
  return env->NewDirectByteBuffer(myClass, 0);
  }

re-using the JNI object :

JNIEXPORT void JNICALL ...foo(JNIEnv * env, jobject obj, jobject handle)
  {
  FieldsHolder* myClass= (FieldsHolder*) env->GetDirectBufferAddress(handle);
  //now we can access the fields again.
  }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!