Java – is there a more portable way to encapsulate pointers than jlong in JNI?

I've seen an example of using long / jlong to allow Java objects to hold C pointers:

class Foo {
    private native long create();
}

struct Foo { };

JNIEXPORT jlong JNICALL Java_Foo_create
  (jnienv *,jobject)
{
    return (jlong) (new Foo);
}

This makes me feel a little nervous because it assumes that a pointer is suitable for 64 bits; This is not true on OS / 400

Is there a more secure solution, such as a Java standard library class that encapsulates C pointers?

Solution

You can use a hash table to store pointers and return the keys of this hash table to the user Like:

std::unordered_map<long,Foo*> handles;
 long newHandle = 0
 ...
  JNIEXPORT jlong JNICALL Java_Foo_create
  (jnienv *,jobject)
   {
       Foo* ptr = new Foo;
       long handle = newHandle;
       handles.insert(std::pair<long,Foo*>(newHandle++,ptr));
       return handle;
   }

You can now get the pointer from HashMap using the handle:

JNIEXPORT void JNICALL Java_Foo_use
  (jnienv *,jobject,jlong handle) {
   auto iter = handles.find(handle);
   if (iter != handles.end()) {
       Foo* ptr = iter->second;
       // use Foo* here
   }
}

This method can also help you check whether the object has been deleted or delete all foo objects that still exist The disadvantage is that accessing HashMap to get pointers can degrade performance In addition, you should use multithreaded access or thread - safe mapping implementation to protect your handle mapping

Or, if you need to implement wrappers for Java, I suggest considering swig (simplified wrapper and interface generator)

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>