[swift-users] Compiling C-usable objects/shared objects

Joe Groff jgroff at apple.com
Mon Apr 11 13:47:53 CDT 2016

> On Apr 11, 2016, at 11:36 AM, Daniel Farina via swift-users <swift-users at swift.org> wrote:
> I've been playing with recent versions of Swift on Linux and think the whole thing is rather neat. I'm most curious about how swift programs might be embeddable in C projects.
> I found a number of documentation artifacts about calling C functions and providing Swift callbacks to C, but none about how to disable mangling of symbols or doing whatever else was necessary to allow C programs to link a Swift .o/.so.
> Also ambiguous to me are runtime requirements, particularly in terms of background threads and memory management. Many of the target C programs I have their in mind have their own memory and concurrency management strategies, e.g. extensions for Python, Ruby, Postgres...
> Is this something that works? Or could be made to work? Has a lot of subtle problems besides throwing "convention(c)" on some functions and turning off mangling?
> Thanks for considering my questions.

Swift uses its own calling convention for Swift-to-Swift calls, so it's not a simple case of disabling mangling. We don't have a supported solution yet for exporting symbols with C linkage and calling conventions, but in master there is a prototype of an attribute, @_cdecl("foo"), which can be used on a function to export it as a C-callable function named foo. For instance:

	func foo(x: Int) -> Int { return x + 1 }

would be usable from C or ObjC as:

	int module_foo(int x);

Note that you still can't define C-compatible struct types from within Swift; they must be defined in C and imported into Swift. Regarding runtime requirements, Swift requires its runtime to function, and there's a requirement that any Swift code that interacts must share the same runtime within a process. Since Swift is not yet ABI-stable, if your primary intent is to provide a shared library for use from C, you may want to statically link the Swift standard library into your .so, and only export C symbols from it for external use. That should keep the "Swiftiness" of the shared library as an internal implementation detail.


More information about the swift-users mailing list