Messages per Month
|Subject:||Re: [jna-dev] Java objects as context for callbacks|
|From:||Timothy Wall (twal...@dev.java.net)|
|Date:||Apr 7, 2008 11:10:50 am|
On Apr 7, 2008, at 1:47 PM, Scott Palmer wrote:
I notice that this problem has already been recognised. The web page states:
----- Java Object arguments In some cases, it would seem convenient to pass a Java object as an opaque pointer for later use by a Java callback method. Unfortunately, this proves problematic in that the native code must become responsible for reference tracking. Until a consistent method or methods of handling these situations is formulated, passing Java objects directly is not supported.
This makes some sense, though it is perhaps overly restrictive. If in my Java code my object will remain alive for the duration of my application for example, then there isn't really any reason that the native side can't just grab a global reference.
Even though this isn't "supported" is current version of JNA capable of passing a Java object for use in a callback method?
I think it'll get kicked out as an IllegalArgumentException. There is some additional basis for allowing Java objects, namely in order to be able to invoke any JAWT or JNIEnv methods, but that usage is pretty narrow.
Have any methods for reference tracking been discussed yet?
I don't have the entire context in my head right now, but you might be able to get away with using weak references on the native side. I think the original context was like this:
install_callback(void (*callback)(void *), void* data)
where some native library code would be holding on to the pointer. you're probably right in that if you keep a reference, the callback can reliably use it, but I was trying to avoid an inadvertent crash with no apparent cause, which would happen if you *don't* keep a reference.
Is adhering to 1.4 compatibility a requirement, or would the use of annotations to help with this problem be permitted?
yes, it is a requirement. at least currently 1.4 compatibility is more important than slight sugar provided by annotations.
Back to the original issue, it's not that hard to associate a context with a callback, given that the callback is an object instance and not just a function pointer. Instead of registering the same callback object in multiple places, you can create a new instance which has the required context embedded within it.