Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Cocoa drawbridge



I have been looking a little bit at a possible way to do some Cocoa bridging using JNIDirect from which has come up on the list from time to time.
http://homepage.mac.com/pcbeard/JNIDirect/ or http://sourceforge.net/projects/jnidirect/
A while back I was trying to get AppleEvent communication working from my application. In the process I got interested in some of the underlying 'mach' stuff for sending and receiving AppleEvents and the possibility of using that to implement a AppleEvent server not dependent on the WindowServer being active that could run as a daemon type process on system startup and across reboots, getting into the system service setup sometimes discussed on the list. A lot of things I know little to nothing about but thought it might be worth the exercise to familiarize myself.
I started coding up some of the references I had come across, QA1123 to list all Unix processes using sysctl calls, bsdps in my JNIDirect stuff. Next was TN2050 which gets into various approaches to get process launch and termination notifications with Carbon, Cocoa, Cocoa/Java and mach.
I thought from what I saw that these would be good background fillers to code up and have done so. Not sure I remember why I thought this at this point but anyhow I considered them prerequisites it would be useful for me to look at.
I coded up the the Mach version, MachNotificaitons.java. The Cocoa/Java didn't appear to work for me but I wasn't too concerned as I thought at the time the more interesting part might be managing the more proper Cocoa/ObjectiveC version with JNIDirect. I started to code that up but decided at some point a more basic, HelloWorld, level example might be more suitable to start out with.
Along the way I came across the code example to generate a ObjC class on the fly in Objc.pdf, the ObjectiveC language guide, /Developer/Documentation/Cocoa/ObjectiveC/Objc.pdf.
So I came up with SyntheticCocoa.java. The intention being dynamically make a simple ObjectiveC class give it a simple void(void) hello world method/selector and I have my start. I noticed later that Patrick Beard had actually indicated this same approach to a alternative Cocoa/Java bridge in later versions of the JNIDirect White Paper. I'm not aware of any related actual coding he did though.
For whatever reasons doing this is not quite as easy as it may sound. I can handle creating the associated structs and running most of the methods to register the generated class with the ObjectiveC runtime to add the methods to it and so on. What I haven't been able to do is allocate an actual instance of the class to invoke my instance method against. Segmentation faults and bus errors one after the other in different areas of code, some seeming to relate to various fields in the objc_class structure some not giving any real clue as to cause. My assumption all along being that somehow I am not filling in the structs correctly. Somehow the compiler is plugging something into them that I am omitting or doing slightly incorrectly. The compiler seems to do a couple of extra tasks for ObjectiveC than it does for say C. Encoding types for one but one or two other things have seemed to me to need setting at compile time so it seemed possible the compiler is doing some initialization for this process that is just escaping me.

To finally start getting to the point eventually I added the following at the end of the class definition method that being...
protected boolean createClassDefinition(String name,String superclassName) {
to which I added the alloc at the end...
objc_msgSend(new_class.getPointer(),getSelector("alloc"));
Just curious really if immediately after defining the class before adding methods would work for the allocate. It did and the code ran all the way through from there out although I had turned off the actual selector invoke because I wasn't sure about parms.
A little more tweaking, deleting System.out.println's adding them in and the like and it no longer worked again. Except now it either got the memory errors or hung on the above 'alloc' call.
So now it's seeming more like a timing dependancy. It can work, it just doesn't often time right to do so? So I sort of searched through the listings to see if anything of like had come up before related to Cocoa threads, memory problems or anything sort of similar. Some printing resulting in Segmentation faults but not a lot in my quick search. That last night, this morning I got to thinking GC. That can figure into some strange timing things. Maybe I'm freeing a pointer before I should and that leads to the memory errors so I started sticking in debug messages in my struct finalize and all of a sudden everything runs through fine. Although GC doesn't appear to be the problem.
What works again?

public SyntheticCocoa() {
System.out.println("NSObject class is \n" + new objc_class(getClass("NSObject")));
// System.out.println("NSString class is \n" + new objc_class(getClass("NSString")));
if (createClassDefinition("SyntheticCocoa","NSObject")) {
SyntheticCocoa_class = getClass(getName());
}
else System.out.println("CocoaNotifications: failed to define class");
helloptr = jnidirect.Linker.newMethodClosure(hellomethod,this);
System.out.println("SyntheticCocoa: adding method " + hellomethod + " with pointer " + helloptr);
ObjectiveCMethod method = new ObjectiveCMethod(class_name,"hello",helloptr,hellomethod,null);
addInstanceMethods(new ObjectiveCMethod[] { method });
System.out.println("after add method SyntheticCocoa class looks like...\n" + new objc_class(SyntheticCocoa_class));

int hellosel = getSelector("hello");
int id = objc_msgSend(SyntheticCocoa_class,alloc);
System.out.println("allocated id is " + id);
objc_msgSend(id,hellosel);
}

public void hello(int self,int _cmd) {
new NSString("HelloWorld!").log();
}

Gets...

2004-04-04 05:10:24.228 java[934] HelloWorld!

After some debugging messages, where and how many somehow seeming to influence how well it works.
But somewhat unsatisfying success. What's the timing dependancy? Why does it work when it works and not work when it doesn't?
Sorry for the length, maybe just a little too early in the morning rambling, but I thought maybe a Java->native alternative particularly a java->Cocoa alternative might be of interest to a few.
Any thoughts on the timing issues appreciated. Why can I cross the bridge sometimes, but sometimes I can't?

Mike Hall <mikehall at spacestar dot net>
<http://www.spacestar.net/users/mikehall>
_______________________________________________
java-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/java-dev
Do not post admin requests to the list. They will be ignored.




Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.