[Prev][Next][Index][Thread]
Re: Objective C bridge (Long)
-
To: info-dylan@ai.mit.edu
-
Subject: Re: Objective C bridge (Long)
-
From: Dustin Voss <d_voss@uswest.net>
-
Date: Mon, 12 Mar 2001 12:45:02 -0500 (EST)
-
References: <200103110920.EAA10493@life.ai.mit.edu>
-
User-Agent: MT-NewsWatcher/3.0 (PPC)
-
Xref: traf.lcs.mit.edu comp.lang.dylan:13118
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!
--