top | item 13487971

(no title)

kinofcain | 9 years ago

With regards to being able to call a Swift function from C, stevetrewick pointed me to @_cdecl early last year[0][1][2]:

    @_cdecl("foobar") public func foobar() {}
I haven't yet used it in anger, but that will compile in Swift 3.

[0]https://news.ycombinator.com/item?id=11650628

[1]https://github.com/apple/swift/commit/013aad13d4245a012cfb76...

[2]https://swiftlang.ng.bluemix.net/#/repl/d68be430e72609717f71...

discuss

order

xenadu02|9 years ago

Be careful; it currently relies on the Objecive-C runtime which is not present on non-Apple platforms.

As the PR says, it also doesn't handle turning throwing functions into errors, nor does it check for collisions.

Another thing you can do is declare a function pointer type in C and assign to it from Swift by calling a C setter function (more or less a small trampoline).

networked|9 years ago

>it currently relies on the Objecive-C runtime which is not present on non-Apple platforms.

Maybe I misunderstand you, but this doesn't seem to be the case, at least not in Swift 3.0-RELEASE. I was able to use @_cdecl for a callback in a Tcl extension (https://tcl.wiki/48057) on Linux.

kinofcain|9 years ago

Exposing a c function from an objective-c file, and then calling into our swift code from there is what we've been doing since before this feature was enabled. That of course also requires the Objective C runtime, but we haven't changed to @_cdecl mainly because I'm more worried about the behavior changing than I am about anyone trying to run our swift code on Linux.

Assigning a block to a c function pointer is an interesting alternative, I thought we tried something like that but I can't remember now.

Hopefully @_cdecl will become a documented and supported feature.

helge5|9 years ago

A nice, I might give that a try, though the

    @_silgen_name("foobar") func foobar()
does seem to work just fine for now. Could change in the future of course, though I wonder how likely it is that the calling convention for this kind of Swift function is actually going to change.

Note that the whole purpose of the function is to enter the Swift side from C just once. After that all is good, you can register any kind of convention-C callbacks.

What I'd like to see is the ability to specify `@convention(c)` not just on types, but also on functions and structs. That would be sweet and reduce the requirement for C wrappers even more.

ewmailing|9 years ago

I was either told or read (during the 2.x time frame) they were likely going to break @_silgen_name. @_cdecl was added to replace this (at least for my usage case), but I think it is still unfinished and not official, hence the leading underscore.

It happens that @_silgen_name didn't break for me in 3.0. But I've been moving to @_cdecl.