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