Once we import the C library of Darwin
into a Swift project, we could use all C function defined there. The library contains most of the functions in C standard library, which provides us some great toolkit in development. It is very easy to import Darwin
, just add import Darwin
in your Swift code. In fact, Foundation
concludes the importing of Darwin
, and in app development we always need UIKit
, which imports Foundation
. Since that, we can use these C functions without doing anything. Moreover, Swift already converts C types in Darwin
into Swift types when importing. For example, a trigonometric function will receive and return values of Double
instead of C double:
func sin(x: Double) -> Double
All these functions are defined in global scope, so we can use them directly:
sin(M_PI_2)
// Output: 1.0
For third party C code, Swift also supplies interoperability to it. As we know, invoking Objective-C code in Swift is very easy. You can expose your Objective-C header file in {product-module-name}-Bridging-Header.h
to Swift. And it is the same with C code. Just import your C header file in the bridging file, so you can call your C method in Swift:
//test.h
int test(int a);
//test.c
int test(int a) {
return a + 1;
}
//Module-Bridging-Header.h
#import "test.h"
//File.swift
func testSwift(input: Int32) {
let result = test(input)
print(result)
}
testSwift(1)
// Output: 2
We have a way to import C functions even without header files or Bridging-Header
. In Swift, there is a symbol called @asmname
, which could map a C function directly to Swift function by the function name. Take the code above for an example, we could delete test.h
and Module-Bridging-Header.h
, and modify the File.swift
file as this:
//File.swift
//Map the `test` function in C to `c_test` in Swift
@asmname("test") func c_test(a: Int32) -> Int32
func testSwift(input: Int32) {
let result = c_test(input)
print(result)
}
testSwift(1)
// Output: 2
This is a way to solve conflicting of a third party C function and the standard C library. We could rename the third party function name to make both happy. Of course, we could also depend on the module name and function name to solve it, which might be a better approach.
@asmname
is also used to "rename" a Swift class or method name to use in C code. This is similar to the @objc
keyword. That is because C will only recognize ascii characters but we could use a much larger character set in Swift.