D/Objective-C Bridge
Michel Fortin
michel.fortin at michelf.com
Tue Sep 18 06:45:08 PDT 2007
On 2007-09-18 02:51:28 -0400, BLS <nanali at nospam-wanadoo.fr> said:
> In your Blog you wrote :
> /D is a statically-typed language, in the same spirit as C++. This
> means that very little information is known at runtime about D objects:
> their name, their members, their methods, almost all of this disappear
> once the program has been compiled. This also mean that you can’t
> dynamically add classes or methods like you can do in Objective-C ..../
>
> I am not that sure. I guess it is possible to implement runtime
> reflection based upon compiletime reflection using D 2.x __traits.
Well, the bridge is written using D 1.x (obviously, since it works on
GDC). But I was speaking of *runtime* refletion, which is limited even
in 2.x.
And the more I think about it, the more I think reflection won't help
much anyway in this case. Reflection would be useful to this bridge if
you could create new classes at runtime and other code could call the
methods of those runtime-created classes... D isn't dynamic enough for
that: you can't call a method you don't know yet on a class you don't
know about.
So even if with runtime reflection you could inspect a D class and
encapsulate it into an Objective-C object all at runtime, you couldn't
do the reverse: create a D class when you receive an Objective-C object.
I'd add that I kind of like the way things are done right now, manually
binding the methods you want. For one thing, it makes it possible to
use different method names in D and in Objective-C, keeping things
clean. For another, it minimize the generated code size. Some D
features (like overloading) would be very hard to map directly to
Objective-C too (unless you use mangled method names).
The syntax to bind methods could use some improvements, although I
doubt it can be improved much without adding new features to the D
language. Something like this, where you could directly associate the
template with the method would be cool, even if I have no idea how it'd
work:
ObjcBindMethod!("setObject:forKey:")
void opIndexAssign(Object obj, Object key) { }
Currently it has to be done this way:
void opIndexAssign(Object obj, Object key) { }
ObjcBindMethod!(opIndexAssign, Object, "setObject:forKey:", Object);
repeating the return type and the argument types so the template can
find the right method (otherwise you'd get unpredictable results with
overloading).
Note that *compile-time* reflection is used here to make that work, in
a rather hacky way. The way it worked orignally, each of these
ObjcBindMethod template instanciation were using a static constructor
to add the method to the statically constructed Objective-C class. This
posed a problem with the ways static constructors work in D, preventing
circular references of modules. I had to find a fix for that.
So now, each of these template instanciation adds an empty struct
member to the class. That said, "empty" isn't compltly right: the
struct has one const static member with the method info for the
Objective-C runtime. Then, when building the Objective-C object, I
iterate over the tuple of the class (which gives non-static members),
find out any struct with a static methodInfo member, and add that
method to the Objective-C class. In other word, I use reflection in the
bridge, but only as a way to improve the syntax for templates (so you
don't have to declare all the bindings at one central place; you can
scatter them in your class definition as you like).
> There is also a project called flectioned on DSource
> http://www.dsource.org/projects/flectioned
Hum, so flectioned looks at the symbols in the executable and use that
for reflection at runtime... looks nice.
--
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/
More information about the Digitalmars-d-announce
mailing list