[Prev][Next][Index][Thread]
Re: Objective C bridge
On Friday, March 9, 2001, at 07:30 PM, Dustin Voss wrote:
> * I want to be able to instantiate and call on Obj C objects.
This is easily done by calling the c functions that Objective-C syntax gets transformed into by the Objective-C preprocessor.
> * 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. :-(
> * 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.
> * Instance variables of the Obj C stub should map to slots of a Dylan
> stub. I considered only supporting methods, to avoid any potential
> garbage collection or reference counting issues with variables, but I
> believe Interface Builder support will require instance variables..
This is interesting. Dylan treats slot access as a method call, Objective-C as a value reference. You'll have to have no public member variables and use accessor functions, which can map to Dylan methods.
> * Obj C exceptions should map to Dylan exceptions. This'll be easy.
How will you do this? I'm interested.
> * I'd like to do all this without relying on any pre-processing.
This is hard: the best way is a toy preprocessor like Apple use for the Obj-C/Java bridge. Some Dylan macros and some hard work on the part of the programmer could do without a preprocessor (I wrote the Dylan Carbon library by hand. Hundreds of melange-c calls. Ugh....)
> I've got some ideas, but it's late and I'm tired, so I'll post them
> tomorrow or this weekend. Sorry about the tease! :-)
Looking forward to it. I can't find the document I wrote on the subject. :-(
Here's a Gwydion d2c-only, Apple Objective-C only (IIRC), calling program. No callbacks or classes.
- Rob.
module: objective-c
// c-include for Apple Objective-C
c-include( "objc/objc.h" );
// Objective-C Types
define constant <objective-c-id> = <statically-typed-pointer>;
define constant <objective-c-class> = <statically-typed-pointer>;
define constant <objective-c-selector> = <statically-typed-pointer>;
// Methods
// get-objective-c-selector
define method get-objective-c-selector( selector-name :: <string> )
=> ( result :: false-or( <objective-c-selector> ) )
let selector-name-c-string = as( <c-string>, selector-name );
let result = call-out( "sel_getUid", ptr:, ptr: selector-name-c-string.raw-value );
if( result = 0 )
#f;
else
as( <objective-c-selector>, result );
end if;
end method get-objective-c-selector;
// get-objective-c-class
define method get-objective-c-class( class-name :: <string> )
=> ( result :: false-or( <objective-c-class> ) )
let class-name-c-string = as( <c-string>, class-name );
let result = call-out( "objc_getClass", ptr:, ptr: class-name-c-string.raw-value );
if( result = 0 )
#f;
else
as( <objective-c-class>, result );
end if;
end method get-objective-c-class;
// obj_msg_send
define method send-objective-c-message( class :: <objective-c-class>, message :: <objective-c-selector> )
=> ( result :: <objective-c-id> )
let result = call-out( "objc_msgSend", ptr:, ptr: class.raw-value, ptr: message.raw-value );
as( <objective-c-id>, result );
end method send-objective-c-message;
// main
define function main(name, arguments)
let alloc = get-objective-c-selector( "alloc" );
let init = get-objective-c-selector( "init" );
let object-class = get-objective-c-class( "NSObject" );
let my-instance = send-objective-c-message( object-class, alloc );
send-objective-c-message( my-instance, init );
format-out("Allocated and initialized NSObject instance.\n");
exit-application(0);
end function main;
// Invoke our main() function.
main(application-name(), application-arguments());
--
Rob Myers - http://www.robmyers.org/dylan
Advanced Free Software Development Tools -
http://www.gwydiondylan.org/