在进行Swift和C之间的相互调用时,有必要先了解一下两种语言之间的类型转换关系:
C 类型 | Swift 类型 |
bool | CBool |
char, signed char | CChar |
unsigned char | CUnsignedChar |
short | CShort |
unsigned short | CUnsignedShort |
int | CInt |
unsigned int | CUnsignedInt |
long | CLong |
unsigned long | CUnsignedLong |
long long | CLongLong |
unsigned long long | CUnsignedLongLong |
wchar_t | CWideChar |
char16_t | CChar16 |
char32_t | CChar32 |
float | CFloat |
double | CDouble |
下在还是先演示一下如何在Swift里对C的方法进行调用,创建一个Swift的项目:
在项目里创建C代码文件:
这个时候会提示你是否要生成Bridging Header,选择创建。
文件创建完成后的代码结构如下,可以看到有一个文件名为:<工程名>-Bridging-Header.h的文件,这就是在Swift和C之间进行桥接的文件。
在项目的配置中可以看到这个桥接文件是在这里指定的,所以如果忘记创建了这个文件也不用担心,自己新建一个在这里指定一下就可以了。
实现C的代码:
MyCFile.h
MyCFile.c
在桥接文件中引入C代码的头文件,非常简单,直接import一下就可以了。
然后在swift文件中就可以直接调用C的方法:
下面我们再添加一些代码,来实现两点:
一、C代码中对Swift代码的调用
二、数据的相互传递(以字符串为例)
MyCFile.h
C对Swift方法的调用,其实相当于是注册一个全局的函数指针,可以参见SwiftCallbackFun的定义。
这个里面有一些OC的语法:
^ 操作符,说明这是一个闭包,也就是Block,Swift里的函数都是以闭包的形式传递进来的。
__nonnull 表示对象不应该为空,因为在混编的时候,Swift编译器并不知道一个Objective-C对象到底是optional还是non-optional,所以在Xcode 6.3引入了一个Objective-C的新特性:nullability annotations,这里可以定义为 __nullable 或 __nonnull 。
MyCFile.c
这里有一个对Swift方法的回调。
main.swift
Swift里的代码,要注意的有两点:
一、在Swift里对C中传入字符串处理的方式
二、要先给全局的Callback赋值,这样才能从C里调用到Swift里的方法。