Swift & C
因为 Swift 是建立在 LLVM 之上的,所以 Swift 是支持与 C 交互的。但是在 Swift 中,让其与 C 混编是一件说起来有点麻烦又不太麻烦的事儿,麻烦就是要实现混编可能需要一些零碎的步骤,不麻烦就是 Swift 也提供了和 C 对应的等价类型来进行转换使用
让 Swift 可调用 C
创建 Module Map 文件
Swift 是建立在 LLVM[1] 之上的,并且两者都是 Chris Lattner 的杰作,所以当然也就支持 LLVM 的 Module[2] 模块,而我们需要使用的是此模块中的 Module Map Language[3]
Module Map Language
是用来描述模块头文件逻辑的,而我们需要为模块创建一个名称为 module.modulemap
的文件,并且文件需要使用 Module Map Language
来描述模块逻辑,以便 Swift 导入
首先我们拥有这样一个结构的目录:
我们拥有两个 C 文件名为 hello.c
和 hello.h
,并且 hello.c
只有一个函数 hello
#include "hello.h"
void hello() {
printf("Hello");
}
我们现在目前是无法进行调用的,这个时候需要在 Hello
目录下创建一个文件名为 module.modulemap
的 Module Map 文件,并且内容为:
module Hello {
header "hello.h"
export *
}
这段表示我们创建了一个名为 Hello
的模块,并且描述了 hello.h
为头文件
导入 Module Map 文件
创建好了 Module Map 文件之后,我们需要让编译器能够找到 Module Map 文件,这样才可以进行调用
我们进入 Build Settings
中,找到 Swift Compiler - Search Paths
部分下的 Import Paths
,把 Module Map 文件的路径添加上:
调用 C 函数
这个时候,便可以在任意的 Swift 文件中导入 Hello 模块并使用 C 函数:
import Hello
func printHello() {
hello()
}
Swift & C 的交互
Swift & C 的等价类型表
在 Apple 的官方文档[4]中,就详细列出了两者之间的等价类型:
C | Swift | Typealias |
---|---|---|
bool | CBool | Bool |
char, signed char | CChar | Int8 |
unsigned char | CUnsignedChar | UInt8 |
short | CShort | Int16 |
unsigned short | CUnsignedShort | UInt16 |
int | CInt | Int32 |
unsigned int | CUnsignedInt | UInt32 |
long | CLong | Int |
unsigned long | CUnsignedLong | UInt |
long long | CLongLong | Int64 |
unsigned long long | CUnsignedLongLong | UInt64 |
wchar_t | CWideChar | UnicodeScalar |
char16_t | CChar16 | UInt16 |
char32_t | CChar32 | UnicodeScalar |
float | CFloat | Float |
double | CDouble | Double |