[Prev][Next][Index][Thread]

Re: Objective C bridge (Long)



In article <200103110920.EAA10493@life.ai.mit.edu>, Rob Myers 
<robm@onetel.net.uk> wrote:

> On Saturday, March 10, 2001, at 12:30 PM, Dustin Voss wrote:
> 
> > I have read Apple's documentation of the Java bridge, but it is way 
> > too skimpy on details to use as a model. 
> 
> Yes. The public headers for the bridge are quite useful, though.
> 
> > That means we need to keep a reference around on the Dylan side of  
> > things, to keep the Dylan stub from getting garbage-collected. When 
> > the framework finally releases the Obj C stub, we can remove the 
> > Dylan  reference. 
> 
> How will Dylan's GC interact with Objective-C's reference counting? 
> If the Dylan GC will scan the Objective-C data structures, it will 
> know when the Dylan objects are no longer referenced. If not, pop the 
> objects in a hashtable with a callback method that gets called to 
> remove them when the Objective-C class is deallocated.

Hmmm. I wouldn't expect Dylan to interact with Obj C's memory or data 
structures at all.

When an Obj C object is finally freed, the runtime calls - dealloc. I 
can override that to call a Dylan method that will free the Dylan 
reference to the bridge class.

> > ...So basically, that's the plan. I don't think there are actually 
> > that many factors to consider here. 
> 
> That sounds good. Looking at Apple's public Objective-C headers, it 
> should be possible to create Objective-C classes and add methods at 
> runtime, I just don't know how to initialize an objc_class struct. 
> I'm working on it. :-)
> 
> PyObjC at http://www.sourceforge.com/ is interesting. It's a Python 
> library to call Objective-C code. Method calls are handled as 
> NSInvocation objects, and id/SEL/Class objects are wrapped for 
> Python.

I will definitely take a look.

> The Java bridge has a parallel java class hierarchy for the obj-c 
> classes. To use Dylan classes in obj-c frameworks, Dylan will either 
> need the same or the classes will have to pose-as the class they're 
> meant to be a subclass of. 

When I create the Obj C stub class, I can specify an existing Obj C 
class to be the superclass. The stub won't need to pose. The Dylan stub 
class won't need to interact with anything but the Obj C superclass -- 
even native Obj C classes don't have that capability. Dylan methods can 
call a super's method by sending a message to the Obj C stub's super.

I think we can get away without creating a parallel hierarchy. Remember 
that the Java/Obj C bridge is meant to be a two-way bridge, but this 
isn't. That lets us cut corners.

> > // An overridden NSView method. 
> > define method draw-rect (view :: <my-subview>, rect :: <rect>) 
> >   view.frame := rect;          // "frame" is inherited Obj-C variable 
> >   view.super-set-background ($red); 
> > end method; 
> 
> View will be the hidden this parameter, and between that and rect there's 
> a hidden sel parameter. The Java bridge automatically converts Strings 
> and other much-used types. The Dylan bridge should definitely do this, 
> although an <NSString> subclass of <string> should work well.

That's a good idea. Better than converting from a <string> each time.

> > // Link the <my-subview> class to the Objective C runtime. This macro 
> > // will add methods and slots to the Dylan class. I think the class 
> > // should contain <function> slots to mimic the method/variable combo 
> > // of Obj C classes and allow delegates. 
> >  
> > define obj-c-bridge <my-subview> ("NSView") 
> >   // Declare Obj C super-class functions to use, but not override. 
> >   inherit "- setBackground:(NSColor)" as super-set-background; 
> >   // Exported Dylan functions     
> >   export draw-rect as "- drawRect:(NSRect)"; 
> > end; 
> 
> Cool. Macrology could build the selector and coerce any parameters 
> that need coercing. Macros can also whack names to strings, which can 
> be useful. This could be combined with the class definition, 
> certainly for the user if not for the macros.

I thought about that. The advantage of declaring the class and then 
declaring the bridge is that the class itself won't carry any excess 
baggage, other than the inherited <obj-c-bridge> slots. But that might 
backfire. I probably should combine the two.

> > In an earlier thread by Rob and, um...Dennis De Mars, they 
> > mentioned a  problem with the Obj C function names and Dylan 
> > functions with keyword  parameters. Basically, all methods on a 
> > generic function must use the  keyword params declared in the 
> > generic, but Obj C doesn't require any  consistency in keyword 
> > parameters. Rather than struggle with this, I can  simply allow 
> > different method names on the Obj C and Dylan sides,  specified by 
> > the programmer. 
> 
> It's probably best to enforce Objective-C naming rules on Dylan, as 
> Dylan has a richer set of characters available to names. For 
> parameter lists, Dylan conventions are better as the lists have to be 
> consistent.
> 
> > > > *  Methods of the Obj C stubs should map to Dylan methods.  
> > >  
> > > If each Obj-C method calls a Dylan callback, no problem. It would 
> > > be  harder, but still possible, to crack the Objective-C method 
> > > name mangling  scheme and add Dylan callbacks to the hashtable 
> > > Objective-C uses to look  up methods. 
> >  
> > I think that's overkill. I bet objc_msgSend will do the job nicely, 
> > once  the stub class is installed into the run-time. 
> 
> That allows the method to be called. It must be registered before it 
> can be called, and Objective-C methods must be registered on a class. 
> There are methods to do this in objc-runtime.h and objc-class.h, but 
> the signature of the Dylan callback has to be right, objects must be 
> coerced, and we need to generate a  signature string (like for Java) 
> for the method.

That code you posted should help with this. What do you mean by 
"signature string"? Something like "alloc:withFrame:"?

> > > > *  Obj C exceptions should map to Dylan exceptions. This'll be 
> > > > easy.  
> > >  
> > > How will you do this? I'm interested. 
> >  
> > This is really easy. I assume the user won't be writing Objective C 
> > code, so any Obj C exceptions will be thrown by the framework and  
> > percolate all the way to the top. I can change the last-resort 
> > exception  handler function. I'll just redirect that to an exported 
> > and  C-compatible Dylan function, which can translate the 
> > NSException to some  <obj-c-exception> object and signal it. Then 
> > the normal Dylan  exception-handling system takes over. 
> 
> That's a very elegant solution.

Thanks!

--