Is there a way to compile native C or C++ code and expose it to Swift on Linux? I can see that several Apple libraries like libdispatch are written in pure C and that you can access them in Swift just by importing them.
To set the example let's say that I have two files Car.c
and Car.h
that define structure named Car
. Is there a way that I can compile them and use them in Swift by writing import statement?
import Car
I've tried writing module.modulemap
file inside directory where .c
, .h
and Package.swift
files are located:
module Car {
header "Car.h"
export *
}
and running swift build
. This yield error:
<unknown>:0: error: unexpected 'commands' value (expected map)
<unknown>:0: error: unable to load build file
I'm using Swift version 3.0-dev (March 24 2016)
[Update 1]
I've contacted Max(mxcl) - one of the creators of Swift Package Manager and he told me to get rid of the modulemap
and put the .c
and .h
files directly in Sources
folder. After I did that package compiled but it's not available as module. Also I can't call any of the defined functions in the .h
file.
If you build a library out of your C code, you can create a system module for it, which can then be imported into Swift, see this answer: Use a C library in Swift on Linux.
Another way to approach this task is to create a bridging header, as suggested by @Philip. Here is an oversimplified example. Let's consider the following C code:
/* In car.h */
int getInt();
/* In car.c */
int getInt() { return 123; }
We will use car.h as the bridging header. The swift source is (in file junk.swift
):
print("Hi from swift!")
var i = getInt()
print("And here is an int from C: \(i)!")
First, create an object file, car.o
, from car.c
:
gcc -c car.c
Now build an executable, junk
, as follows:
swiftc -import-objc-header car.h junk.swift car.o -o junk
Running the executable gives:
$ ./junk
Hi from swift!
And here is an int from C: 123!
The -import-objc-header
option is hidden. To see it and a bunch of other hidden options, run:
swiftc -help-hidden
I did this using Swift 3.0 development snapshot for Ubuntu 14.04 from April 12, available here: https://swift.org/builds/development/ubuntu1404/swift-DEVELOPMENT-SNAPSHOT-2016-04-12-a/swift-DEVELOPMENT-SNAPSHOT-2016-04-12-a-ubuntu14.04.tar.gz
Now, if you want to use C++, you will need to create a wrapper, written in a C++ source file and compiled with a C++ compiler, but with functions callable from C by using extern "C"
. Those functions can then be called from Swift as any C function. See, for example, this answer: Can I mix Swift with C++? Like the Objective - C .mm files
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With