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

Re: Objective C bridge



I have read Apple's documentation of the Java bridge, but it is way too 
skimpy on details to use as a model.

(We'll need some vocab. I will use "Obj C stub", "Dylan stub", and 
"bridge class" for the combination of the two. I'll use "me" or "we" 
indiscriminately.)

The keys were the flexibility of the Obj C run-time and the dynamicism 
of Dylan. I can create Objective C and Dylan stubs at run-time, use 
plain C as an mediating interface, vivisect the Objective C classes, and 
make the Dylan stub transparent.

The bridge class will have an interesting life cycle. I expect it could 
be instantiated either on the Dylan or Obj C side of things.

If Obj C instantiates the bridge class, it'll be the framework doing it. 
I'm assuming the user won't be writing any Objective C code of his own. 
I think we can trust the framework to properly allocate and release the 
Obj C stub. So long as the Obj C stub exists, the Dylan stub should 
also. 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.

If Dylan instantiates the bridge class, then we just need to keep an 
extra Dylan reference around only if the Obj C side retains the Obj C 
stub, and release that reference when all the Obj C references are also 
released.

The bridge class will have instance variables. It will keep those 
variables in the Obj C stub, since Obj C code will need direct access to 
the variables. The Dylan stub can access the variables through setters 
and getters that deal directly with the Obj C object structure.

The bridge class will also have methods, some of which will be inherited 
from an Objective C superclass. Those inherited methods will be 
accessible to Dylan code via objc_msgSend. Non-inherited or overridden 
methods will be written in Dylan, and exposed to Obj C code via C 
callbacks.

So basically, that's the plan. I don't think there are actually that 
many factors to consider here.

I'd like the syntax to look something like this, but I'm not sure 
obj-c-bridge-definer will be evaluated at run-time or compile-time. For 
this concept, it'll need to be run-time. Additionally, I don't have as 
much practice with Dylan as I'd like, so this syntax may prove 
impractical.

---------------------------------------------------------------------
// Sub-class of NSView with Dylan-specific instance variables.
define class <my-subview> (<obj-c-bridge>)
  slot my-slot;
end class;

// 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;

// 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;

begin
  ...
end;
----------------------------------------------------------------------

I've read some of the issues you guys have posted.

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.

Rob wrote:

> > *  I want to be able to create an Obj C stub that fits in the Obj C  
> > class hierarchy, so I can subclass NSWindowController (for example). 
> 
> It's more of a facade, I think. See how Apple make proxies for Java 
> Objects. I came up with an incredibly overblown solution using NSProxy, 
> but a simple facade is much better, I think. :-) I can't figure out how 
> Objective-C classes are added to the dispatch table in the Objective-C 
> runtime. I think it's runtime-specific. :-(

It may well be. The runtime offers classes for dispatching messages, 
adding classes, finding classes by name, retrieving variables and 
methods of a class by name, and editing a class's method list. Looks 
easy for the OS X runtime.

> > *  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.

> > *  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.



References: