

Interoperating Between Objective-C and Rust - adamnemecek
http://sasheldon.com/blog/2014/11/28/interoperating-between-objective-c-and-rust/

======
kibwen
Very impressive! This post demonstrates a great deal of understanding of the
semantics of both languages, and the resultant interface looks both usable and
thorough. I especially enjoyed the use of a Rust macro to emulate the syntax
of Objective-C message passing, as well as the demonstration of the utility of
"phantom" type parameters.

------
comex
Just to bring up something I've been thinking about, Rust would have a lower
impedance mismatch with Swift interfaces - memory safe APIs, with a more
C-like method syntax, more strongly typed in general (optionals, generics...),
more functional (although AFAIK there aren't currently many Swift-specific
APIs, as opposed to Objective-C ports), and so on. Its binary module system
also matches Rust somewhat better than Objective-C's basically #include based
system. Unfortunately, Swift's runtime, aside from being more complicated than
Objective-C's, is completely undocumented (and closed-source), so it would
take a good bit of reverse engineering to create a bridge.

~~~
sjwright
You can do this sort of thing with Objective C precisely because the layer
between ObjC and C is so clean and concise. It's a strict superset of the C
language; the C at its core is pure and entirely unmolested.

What makes interoperability possible is Rust's existing C interop.

Rust doesn't have any Swift interop.

------
one-more-minute
Very cool – and oddly relevant to me since as well as taking an interest in
Rust recently, I'm also writing an Objective-C bridge for Julia (which I'll
write about soon).

Like the languages themselves the bridges are polar opposites, of course –
static and safe vs. flexible and interactive, etc. It's great to see it (and
learn from it) being done on the other side of those tradeoffs.

------
dmitryskiba
Strictly speaking, [string UTF8String] is equivalent to '((const char
<star>(<star>)(id, SEL))objc_msgSend)(string, selector)'. Since objc_msgSend
is vararg function, it will promote it's arguments, so for example method
taking float will be called with double. Casting to a proper function type
works around that.

~~~
sasheldon
Oh good point, I hadn't considered vararg promotion!

Do you know if casting to a function also make objc_msgSend_stret and
objc_msgSend_fpret unnecessary? I haven't yet worked with any methods that
return structs or floating point values, so I haven't had to deal with them
yet.

Edit: Oh, nope, my bad, objc_msgSend_stret is the one where you definitely
have to cast: [http://blog.lazerwalker.com/blog/2013/10/12/the-
objective-c-...](http://blog.lazerwalker.com/blog/2013/10/12/the-objective-c-
runtime-and-objc-msgsend-stret)

~~~
teacup50
As you discovered, _stret/_fpret remain necessary.

objc_msgSend()'s type is not expressible in C; the only time it is correct to
call objc_msgSend without a cast is when calling a method IMP with the literal
vararg type of id (*method) (id self, SEL sel, ...);

In other words, essentially never.

------
cfrs
Foundation is actually open source
[http://www.opensource.apple.com/source/CF/CF-855.11/CFString...](http://www.opensource.apple.com/source/CF/CF-855.11/CFString.c)

~~~
gilgoomesh
That's CoreFoundation, not Foundation. CoreFoundation is plain C and
relatively small in feature set. Foundation is Objective-C and much larger.

It's a lot easier to work with the Foundation Objective-C API. They both
manipulate the same data structures (or nearly the same with zero-cost
bridging) but Foundation is far less verbose and a little more dynamic (no
need for manual buffer allocations and configuring callback structures).

~~~
dmitryskiba
There is Foundation implementation based on CoreFoundation:
[https://github.com/apportable/Foundation](https://github.com/apportable/Foundation)

------
xngzng
Great writeup. More interested though on how one can use Rust to write iOS, OS
X and Android framework/library. This will make Rust replacing C++ for cross
platform codes.

~~~
pjmlp
Only if Rust provides something comparable with Qt, SDL, Cocos-2D,
openFrameworks....

Otherwise having platform FFI pain, C and C++ interop pain is just too much.

------
the_mitsuhiko
That's interesting. I always had problems using objc_msgSend via FFIs because
if I remember correctly it was implemented via setjmp and longjmp.

------
zerr
Huh, Obj-C got its stairway to heaven :)

------
lukeh
Really impressive stuff.

