[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [platform-swt-dev] What is OS.JNIGetObject for in SWT Cococa?
|
On Oct 10, 2008, at 15:12, Andrey Tarantsov wrote:
Hi,
Regarding the tags, they are used to store a reference to a Java
object that corresponds to a given Cocoa object. (Obviously you
cannot pass a Java pointer into Cocoa, so we have to pass Java
object references which are only available from JNI only, hence the
JNI calls NewGlobalRef, DeleteGlobalRef and JNIGetObject. As far as
I remember, the int -> Object mapping you're talking about is
managed by the JVM itself, not by SWT.)
The Java object id is stored in a "tag" field of Cocoa objects,
however there may be issues with this approach because Cocoa
sometimes wants to use the "tag" field for its own needs. Here's a
letter my colleage Mikhail Kalugin has posted a few month ago to
this mailing list:
Recently I met a weird problem with Display.getFocusControl() method:
it was failing with NPE on "OS.JNIGetObject(tag);" call (line 1083).
At first glance, this call doesn't do anything that can throw NPE.
After some investigations I've found the reason — tag wasn't an JNI
object reference. It was a natively set tag by Cocoa itself. I was
using NSAlert class which uses tags for the content view. So when my
application was asking for a focus control, SWT was encountering
NSAlert's window, asking for a tag in order to restore SWT's class and
then failing.
Regarding concretely this issue, the solution is simple: the
OS.JNIGetObject(tag); line can be surrounded by a try..catch block.
However, I think that problem has more deep roots. Really, why does
SWT use tag()/setTag() methods for storing JNI refs? Since Cocoa can
use tag field itself, it doesn't look as a secure solution. There are
methods for creating/reading/updating instance variables in Cocoa
object. So it would be possible to use some variable like
"swt_jni_ref" to store refs.
He was recommended to open a bug to track it. I believe what you
should do for your port is:
1) add a uniquely named field to your Cocoa objects instead of a
generic "tag" field (e.g. "swt_tag");
2) instead of adding tag/setTag methods to each Cocoa object you
define on SWT side, just read/write that "swt_tag" field directly
using Objective-C runtime calls.
And yes, if D virtual machine does not readily map objects to
integers (how does it handle native callbacks then?), you can manage
the mapping yourself.
--
Andrey.
_______________________________________________
platform-swt-dev mailing list
platform-swt-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/platform-swt-dev
Tanks for the reply.
It sounds strange that Cocoa would set a tag, the documentation says
this:
"Tag values are not used internally; they are only changed by external
invocations of setTag:"
http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSControl_Class/Reference/Reference.html#/
/apple_ref/occ/instm/NSControl/tag
Do you know if he opened a bug for this?
D code compiles into native machine code so there is no virtual machine.