C/FFI interop


(Fastmail) #1

What are the current facilities planned or in development for FFI? Just as Swift functions can be exposed through @objc, how would I add a similar capability for pure C? Is this what, in fact, module maps might be for?

I ask since writing high performance native code for dynamic languages is currently done in C, and that’s a pretty bad idea. It would be great for Swift if people started writing native bindings in it as opposed to C, but it probably needs at the least a way to re-export global public functions for C/C++.

Please let me know if I should take this to swift-dev or swift-evolution!

Tom


(David Turnbull) #2

No buts. It's started already. For example, here's my Mac and Linux OpenGL
loader that's 100% pure swift. Over 3000 commands cleanly imported into
Swift without a single line of C or H code.

https://github.com/AE9RB/SwiftGL

Swift isn't a dynamic language that needs an ecosystem of C packages to
supplement performance while at the same time being difficult to integrate
with C. It's exactly not that in every way. Come on in, the water's fine.

-david

···

On Wed, Dec 23, 2015 at 8:30 AM, swizzlr via swift-users < swift-users@swift.org> wrote:

It would be great for Swift if people started writing native bindings in
it as opposed to C, but...


(Brent Royal-Gordon) #3

What are the current facilities planned or in development for FFI? Just as Swift functions can be exposed through @objc, how would I add a similar capability for pure C? Is this what, in fact, module maps might be for?

I ask since writing high performance native code for dynamic languages is currently done in C, and that’s a pretty bad idea. It would be great for Swift if people started writing native bindings in it as opposed to C, but it probably needs at the least a way to re-export global public functions for C/C++.

Please let me know if I should take this to swift-dev or swift-evolution!

Swift does not require a foreign function interface—it can directly call C functions. Sometimes Swift generates a trampoline to do this, but often not even that. The module map basically just tells Swift which headers and binaries make up a particular module. There's generally no need to write any bridging code—it just works.

There are a few C constructs that Swift doesn't support very well, like unions and fixed-size arrays in structs. In those cases, you may need to write some C functions which perform the operations that can't be easily expressed in Swift, but these functions would just be plain old C with no special bridging involved. Similarly, you may choose to write wrappers around some of your library's C constructs to make them more convenient to use—for instance, if your library has a struct called `foo` and an operation on that struct called `frobnicate_foo()`, you might extend `foo` to add a `frobnicate()` method to it. But this is purely optional, and you would write it in plain old Swift.

Though Apple's platforms are most commonly associated with Objective-C, there's a lot of C over there too. Swift works very well with it—this stuff is fast, as transparent as it can be, and frequently exercised.

In short: Just try it. It's pretty easy.

···

--
Brent Royal-Gordon
Architechies


(Jason Dusek) #4

I think the OP was asking not about importing C symbols into Swift but
rather exporting Swift to C.

···

On Wed, 23 Dec 2015 at 15:18 Brent Royal-Gordon via swift-users < swift-users@swift.org> wrote:

> What are the current facilities planned or in development for FFI? Just
as Swift functions can be exposed through @objc, how would I add a similar
capability for pure C? Is this what, in fact, module maps might be for?
>
> I ask since writing high performance native code for dynamic languages
is currently done in C, and that’s a pretty bad idea. It would be great for
Swift if people started writing native bindings in it as opposed to C, but
it probably needs at the least a way to re-export global public functions
for C/C++.
>
> Please let me know if I should take this to swift-dev or swift-evolution!

Swift does not require a foreign function interface—it can directly call C
functions. Sometimes Swift generates a trampoline to do this, but often not
even that. The module map basically just tells Swift which headers and
binaries make up a particular module. There's generally no need to write
any bridging code—it just works.

There are a few C constructs that Swift doesn't support very well, like
unions and fixed-size arrays in structs. In those cases, you may need to
write some C functions which perform the operations that can't be easily
expressed in Swift, but these functions would just be plain old C with no
special bridging involved. Similarly, you may choose to write wrappers
around some of your library's C constructs to make them more convenient to
use—for instance, if your library has a struct called `foo` and an
operation on that struct called `frobnicate_foo()`, you might extend `foo`
to add a `frobnicate()` method to it. But this is purely optional, and you
would write it in plain old Swift.

Though Apple's platforms are most commonly associated with Objective-C,
there's a lot of C over there too. Swift works very well with it—this stuff
is fast, as transparent as it can be, and frequently exercised.

In short: Just try it. It's pretty easy.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Eric Wing) #5

I am also interested in this same general question, but maybe a little
simpler. I simply would like to call Swift from C.

My use case is much simpler though. I have a lot of code written in C,
often at pretty low level and/or platform level. It may not be easy to
rewrite this in pure Swift. But higher-level functionality could be
more easily written in Swift, so it would be nice to call out to Swift
from C.

One specific example I'm thinking of is Android and the NDK. On
Android, everything starts in Java. You can cross into C via the NDK.
But once in C, you still need a way to reach Swift.

On Apple platforms, I achieved this by going through Objective-C
(pre-Xcode 7). I created Swift classes that could be called from
Obj-C. Then from C, I crossed into Obj-C, and then finally Swift. But
on Swift on Linux doesn't seem to come with Obj-C. Furthermore, I
noticed that with Xcode 7+, my little C/Obj-C/Swift trampolines don't
seem to work any more unless I make my Swift classes full subclasses
of NSObject, which I was trying to avoid because I expected Linux
Obj-C support to be extremely minimal even if it were available.

Thanks,
Eric

···

On 12/23/15, Thomas Catterall via swift-users <swift-users@swift.org> wrote:

Indeed I was - I'm quite sorry for the confusion, I didn't make my intent
clear as I should have, such as through example. What I'm referring to is,
for instance, offering a way for a Ruby library to interface with a module
written in Swift to communicate with Redis (as an example, not something I'm
thinking too seriously about).

Sent from my iPhone

On 23 Dec 2015, at 19:20, Jason Dusek <jason.dusek@gmail.com> wrote:

I think the OP was asking not about importing C symbols into Swift but
rather exporting Swift to C.


(Fastmail) #6

Indeed I was - I'm quite sorry for the confusion, I didn't make my intent clear as I should have, such as through example. What I'm referring to is, for instance, offering a way for a Ruby library to interface with a module written in Swift to communicate with Redis (as an example, not something I'm thinking too seriously about).

···

Sent from my iPhone

On 23 Dec 2015, at 19:20, Jason Dusek <jason.dusek@gmail.com> wrote:

I think the OP was asking not about importing C symbols into Swift but rather exporting Swift to C.

On Wed, 23 Dec 2015 at 15:18 Brent Royal-Gordon via swift-users <swift-users@swift.org> wrote:
> What are the current facilities planned or in development for FFI? Just as Swift functions can be exposed through @objc, how would I add a similar capability for pure C? Is this what, in fact, module maps might be for?
>
> I ask since writing high performance native code for dynamic languages is currently done in C, and that’s a pretty bad idea. It would be great for Swift if people started writing native bindings in it as opposed to C, but it probably needs at the least a way to re-export global public functions for C/C++.
>
> Please let me know if I should take this to swift-dev or swift-evolution!

Swift does not require a foreign function interface—it can directly call C functions. Sometimes Swift generates a trampoline to do this, but often not even that. The module map basically just tells Swift which headers and binaries make up a particular module. There's generally no need to write any bridging code—it just works.

There are a few C constructs that Swift doesn't support very well, like unions and fixed-size arrays in structs. In those cases, you may need to write some C functions which perform the operations that can't be easily expressed in Swift, but these functions would just be plain old C with no special bridging involved. Similarly, you may choose to write wrappers around some of your library's C constructs to make them more convenient to use—for instance, if your library has a struct called `foo` and an operation on that struct called `frobnicate_foo()`, you might extend `foo` to add a `frobnicate()` method to it. But this is purely optional, and you would write it in plain old Swift.

Though Apple's platforms are most commonly associated with Objective-C, there's a lot of C over there too. Swift works very well with it—this stuff is fast, as transparent as it can be, and frequently exercised.

In short: Just try it. It's pretty easy.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users