Spook Spook - 1 month ago 10
Android Question

Android NDK, keeping live C++ objects

I've got a following problem. I want to write an Android application, which uses my legacy C++ classes. I have to keep a C++ object alive during the whole application lifetime.

I wrote a similar application in C# and solved the problem by passing a pointer to a C++ class to C# and storing it there using IntPtr. Then, when I wanted to call a method on that object, I simply passed that pointer again to C++, converted to a class pointer and called a method on it.

How can I achieve similar result in Java and Android NDK? Does Java support storing pointers?

Answer Source

Yes, you can do the exact same than what you did in C#.

To create your new C++ Object:

jlong
Java_package_name_new(JNIEnv *, jobject) {
  return (long)(new CPP_Object()); 
}

You can store the return value of this method in a Java ptr variable, and pass it to all NDK methods that need it:

void
Java_package_name_doSomething(JNIEnv *, jobject, jlong ptr) {
  CPP_Object *obj = (CPP_Object *)ptr;
  // do whatever you want with the object
}

And finally delete it with something like:

void
Java_package_name_delete(JNIEnv *, jobject, jlong ptr) {
  delete (CPP_Object *)(ptr);
}

Instead of passing ptr to all methods that need it, you can also get it and set it directly from the NDK part using the SetLongField and GetLongField methods: this allows the Java ptr variable to be managed only from the NDK part of the code, which I find safer and easier to manage.