Swift 与 C 语言混合编程
前言
- 作为一种可与 Objective-C 相互调用的语言,Swift 也具有一些与 C 语言的类型和特性,如果你的代码有需要,Swift 也提供了和常见的 C 代码结构混合编程的编程方式。
1、基本数据类型
Swift 提供了一些和 C 语言的基本类型如
char,int,float,double等价的 Swift 基本数据类型。然而,这些 Swift 的核心基本类型之间并不能隐式的相互转换,如Int。因此,只有你的代码明确要求它们时再使用这些类型,而Int可以在任何你想使用它的时候使用。C 类型 Swift 类型 boolCBoolchar, signed charCCharunsigned charCUnsignedCharshortCShortunsigned shortCUnsignedShortintCIntunsigned intCUnsignedIntlongCLongunsigned longCUnsignedLonglong longCLongLongunsigned long longCUnsignedLongLongwchar_tCWideCharchar16_tCChar16char32_tCChar32floatCFloatdoubleCDouble
2、枚举
Swift 引进了用宏
NS_ENUM来标记的任何 C 风格的枚举类型。这意味着无论枚举值是在系统框架还是在自定义的代码中定义的,当他们导入到 Swift 时,他们的前缀名称将被截断。Swift 也引进了标有
NS_OPTIONS宏选项。而选项的行为类似于引进的枚举,选项还可以支持一些位操作,如&,| 和 ~。在 Objective-C 中,你用一个空的选项设置标示恒为零 (0)。在 Swift 中,使用 nil 代表没有任何选项。
看这个 Objective-C 枚举
// Objective-C typedef NS_ENUM(NSInteger, UITableViewCellStyle) { UITableViewCellStyleDefault,
UITableViewCellStyleValue1,
UITableViewCellStyleValue2,
UITableViewCellStyleSubtitle
};
在 Swift 中这样来实现
// Swift enum UITableViewCellStyle: Int { case Default
case Value1
case Value2
case Subtitle
}
当你需要指向一个枚举值时,使用以点 (.) 开头的枚举名称
// Swift let cellStyle: UITableViewCellStyle = .Default
3、指针
Swift 尽可能避免让你直接访问指针。然而,当你需要直接操作内存的时候,Swift 也为你提供了多种指针类型。下面的表使用 Type 作为占位符类型名称来表示语法的映射。
对于参数,使用以下映射:
C 句法 Swift 句法 const void *CConstVoidPointervoid *CConstPointer<Type>const Type *CUnsignedCharType *CMutablePointer<Type>对于返回类型,变量和参数类型的多层次指针,使用以下映射:
C 句法 Swift 句法 void *COpaquePointerType *UnsafePointer<Type>对于类(class)类型,使用以下映射:
C 句法 Swift 句法 Type * const *CConstPointer<Type>Type * __strong *CMutablePointer<Type>Type **AutoreleasingUnsafePointer<Type>
3.1 C 可变指针
当一个函数被声明为接受
CMutablePointer<Type>参数时,这个函数可以接受下列任何一个类型作为参数。nil,作为空指针传入一个
CMutablePointer<Type>类型的值一个操作数是
Type类型的左值的输入输出表达式,作为这个左值的内存地址传入一个输入输出
Type[]值,作为一个数组的起始指针传入,并且它的生命周期将在这个调用期间被延长如果你像这样声明了一个函数
// Swift func takesAMutablePointer(x: CMutablePointer<Float>) { /*...*/ }
那么你可以使用以下任何一种方式来调用这个函数
// Swift var x: Float = 0.0
var p: CMutablePointer<Float> = nil
var a: [Float] = [1.0, 2.0, 3.0] takesAMutablePointer(nil)
takesAMutablePointer(p)
takesAMutablePointer(&x)
takesAMutablePointer(&a)
当函数被声明使用一个
CMutableVoidPointer参数,那么这个函数接受任何和CMutablePointer<Type>相似类型的Type操作数。如果你这样定义了一个函数
// Swift func takesAMutableVoidPointer(x: CMutableVoidPointer) { /*...*/ }
那么你可以使用以下任何一种方式来调用这个函数
// Swift var x: Float = 0.0, y:Int = 0
var p: CMutablePointer<Float> = nil, q: CMutablePointer<Int> = nil
var a: [Float] = [1.0, 2.0, 3.0], b: Int = [1, 2, 3] takesAMutableVoidPointer(nil)
takesAMutableVoidPointer(p)
takesAMutableVoidPointer(q)
takesAMutableVoidPointer(&x)
takesAMutableVoidPointer(&y)
takesAMutableVoidPointer(&a)
takesAMutableVoidPointer(&b)
3.2 C 常指针
当一个函数被声明为接受
CConstPointer<Type>参数时,这个函数可以接受下列任何一个类型作为参数。nil,作为空指针传入一个
CMutablePointer<Type>,CMutableVoidPointer,CConstPointer<Type>,CConstVoidPointer,或者在必要情况下转换成CConstPointer<Type>的AutoreleasingUnsafePointer<Type>值一个操作数是
Type类型的左值的输入输出表达式,作为这个左值的内存地址传入一个
Type[]数组值,作为一个数组的起始指针传入,并且它的生命周期将在这个调用期间被延长如果你这样定义了一个函数
// Swift func takesAConstPointer(x: CConstPointer<Float>) { /*...*/ }
那么你可以使用以下任何一种方式来调用这个函数
// Swift var x: Float = 0.0
var p: CConstPointer<Float> = nil takesAConstPointer(nil)
takesAConstPointer(p)
takesAConstPointer(&x)
takesAConstPointer([1.0, 2.0, 3.0])
当函数被声明使用一个
CConstVoidPointer参数,那么这个函数接受任何和CConstPointer<Type>相似类型的Type操作数。如果你这样定义了一个函数
// Swift func takesAConstVoidPointer(x: CConstVoidPointer) { /*...*/ }
那么你可以使用以下任何一种方式来调用这个函数
// Swift
var x: Float = 0.0, y: Int = 0
var p: CConstPointer<Float> = nil, q: CConstPointer<Int> = nil takesAConstVoidPointer(nil)
takesAConstVoidPointer(p)
takesAConstVoidPointer(q)
takesAConstVoidPointer(&x)
takesAConstVoidPointer(&y)
takesAConstVoidPointer([1.0, 2.0, 3.0])
takesAConstVoidPointer([1, 2, 3])
3.3 自动释放不安全指针
当一个函数被声明为接受
AutoreleasingUnsafePointer<Type>参数时,这个函数可以接受下列任何一个类型作为参数。nil,作为空指针传入一个
AutoreleasingUnsafePointer<Type>值其操作数是原始的,复制到一个临时的没有所有者的缓冲区的一个输入输出表达式,该缓冲区的地址传递给调用,并返回时,缓冲区中的值加载,保存,并重新分配到操作数。
注意:这个列表没有包含数组。
如果你这样定义了一个函数
// Swift func takesAnAutoreleasingPointer(x: AutoreleasingUnsafePointer<NSDate?>) { /*...*/ }
那么你可以使用以下任何一种方式来调用这个函数:
// Swift var x: NSDate? = nil
var p: AutoreleasingUnsafePointer<NSDate?> = nil takesAnAutoreleasingPointer(nil)
takesAnAutoreleasingPointer(p)
takesAnAutoreleasingPointer(&x)
注意:C 语言函数指针没有被 Swift 引进。
4、全局常量
- 在 C 和 Objective-C 语言源文件中定义的全局常量会自动地被 Swift 编译引进并做为 Swift 的全局常量。
5、预处理指令
- Swift 编译器不包含预处理器。取而代之的是它充分利用了编译时属性生成配置和语言特性来完成相同的功能。因此 Swift 没有引进预处理指令。
5.1 简单宏
在 C 和 Objective-C 中通常使用的
#define指令定义的一个宏常数,在 Swift 中可以使用全局常量来代替。由于简单的用于定义常量的宏会被直接被映射成 Swift 全局量,Swift 编译器会自动引进在 C 或 Objective-C 源文件中定义的简单宏。例如: 一个全局定义
#define FADE_ANIMATION_DURATION 0.35,在 Swift可以使用let FADE_ANIMATION_DURATION = 0.35来更好的表述。
5.2 复杂宏
- 在 C 和 Objective-C 中使用的复杂宏在 Swift 中并没有与之对应的定义。复杂宏是那些不用来定义常量的宏,而是用来定义包含小括号 () 函数的宏。你在 C 和 Objective-C 使用复杂的宏是用来避免类型检查的限制和相同代码的重复劳动。然而,宏也会产生 Bug 和重构的困难。在 Swift 中你可以直接使用函数和泛型来达到同样的效果。因此,在 C 和 Objective-C 源文件中定义的复杂宏在 Swift 是不能使用的。
5.3 编译配置
Swift 代码和 Objective-C 代码以不同的方式进行条件编译。Swift 代码可以根据生成配置的评价配进行有条件的编译。生成配置包括
true和false字面值,命令行标志,和下表中的平台测试函数。你可以使用-D <#Flag#>指定命令行标志。函数 有效参数 os()OSX, iOSarch()x86_64, arm, arm64, i386- 注意:
arch(arm)的生成配置不会为 64 位 arm 设备返回true,当代码运行在为 32 位的 iOS 模拟器器时,arch(i386)的生成配置返回true。
- 注意:
一个简单的条件编译需要以下代码格式。
#if build configuration
statements
#else
statements
#endif
一个由零个或多个有效的 Swift 语句声明的
statements,可以包括表达式,语句和控制流语句。你可以添加额外的构建配置要求,条件编译说明用&&和||操作符以及!操作符,添加条件控制块用#elseif。#if build configuration && !build configuration
statements
#elseif build configuration
statements
#else
statements
#endif
与 C 语言编译器的条件编译相反,Swift 条件编译语句必须完全是自包含和语法有效的代码块。这是因为 Swift 代码即使没有被编译,也要全部进行语法检查。
Swift 与 C 语言混合编程的更多相关文章
- 【转载】ANSYS的APDL与C语言混合编程(实例)
原文地址:http://www.cnblogs.com/lyq105/archive/2010/05/04/1727557.html 本文讨论的不是利用C语言为ANSYS写扩展(或者说是用户子程序), ...
- Java语言与C语言混合编程(2)--在Java中调用C语言本地库
在上一篇文章中介绍了Java语言中的native关键字,以及Java语言调用C语言的编译生成本地动态链接库(DLL)实现加法运算的小例子,本文通过一个更加详细的例子,深入讲解Java语言调用C语言的函 ...
- Java语言与C语言混合编程(1)--Java native 关键字
一. 什么是 native Method 简单地讲,一个 native Method 就是一个java调用非java代码的接口.一个 native Method 是这样一个java的方法:该方法的实现 ...
- Android程序中,内嵌ELF可执行文件-- Android开发C语言混合编程总结
前言 都知道的,Android基于Linux系统,然后覆盖了一层由Java虚拟机为核心的壳系统.跟一般常见的Linux+Java系统不同的,是其中有对硬件驱动进行支持,以避开GPL开源协议限制的HAL ...
- iOS - Swift 与 C 语言交互编程
前言 作为一种可与 Objective-C 相互调用的语言,Swift 也具有一些与 C 语言的类型和特性,如果你的代码有需要,Swift 也提供了和常见的 C 代码结构混合编程的编程方式. 1.基本 ...
- Dart 调用C语言混合编程
Dart 调用C语言本篇博客研究Dart语言如何调用C语言代码混合编程,最后我们实现一个简单示例,在C语言中编写简单加解密函数,使用dart调用并传入字符串,返回加密结果,调用解密函数,恢复字符串内容 ...
- SQL+C#:一次多语言混合编程的经验总结
1.用JAVA做,采取轮询策略: 2.用sql语言+C#混合编程,采取触发策略
- Swift语言与Objective-C语言混合编程
首先创建一个Swift的Single View工程 然后直接在工程中新建OC文件: 然后选择OC语言之后会问你是否自动创建OC和Swift的中间文件: 然后工程文件夹里就有了三个文件: 现在OC头文件 ...
- 《从零开始学Swift》学习笔记(Day 71)——Swift与C/C++混合编程之数据类型映射
原创文章,欢迎转载.转载请注明:关东升的博客 如果引入必要的头文件,在Objective-C语言中可以使用C数据类型.而在Swift语言中是不能直接使用C数据类型,苹果公司为Swift语言提供与C语言 ...
随机推荐
- POJ 1930 Dead Fraction (循环小数-GCD)
题意:给你一个循环小数,化成分数,要求分数的分母最小. 思路:暴力搜一遍循环节 把循环小数化分数步骤: 纯循环小数化分数 纯循环小数的小数部分可以化成分数,这个分数的分子是一个循环节表示的数,分母各位 ...
- NodeMCU入门(1):刷入At固件,透传数据到TcpServer和Yeelink平台
准备工作 1. NodeMCU LUA ESP8266 CP2102 WIFI Internet Development Board,仔细看背面可以看出自带cp2102模块,可以通过普通的手机充电 ...
- 【LOJ】#150. 挑战多项式
原题链接 多项式全家桶!快乐!(好像少个除法,不过有除法好像不太快乐) (说真的这是我第一次写exp和开根...水平不行.. 从最基础要实现的操作开始吧.. 多项式取模\(x^n\) 这个..很简单了 ...
- Mysql mysqld_safe启动与myslqd启动坑
一.用mysqld_safe启动时候无法看到报错信息. 二.用mysqld启动时候可以看到日志实时打印.
- BZOJ1030 [JSOI2007]文本生成器 AC自动机 动态规划
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1030 题意概括 给出n个模式串,问长度为m的串中有多少个至少含有这n个模式串中的任意一个. 注意, ...
- 6-2 S树 uva712
这题关键是 反转 查询是固定按照x1x2x3来的 那么先收集前面的顺序 然后在数组里面直接调用即可 比如前面的树是 x3 x1 x2 就把这个当作数组下标 最左边的树是 1<&l ...
- 8. 博客系统| 富文本编辑框和基于bs4模块防御xss攻击
views.py @login_required def cn_backend(request): article_list = models.Article.objects.filter(user= ...
- python新手总结(二)
random模块 随机小数 random uniform 随机整数 randint randrange 随机抽取 choice sample 打乱顺序 shuffle random.random() ...
- Ubuntu pkg_resources.DistributionNotFound: The 'Scrapy==1.0.3' distribution was not found and is required by the application
在Ubuntu16.0.4上安装scrapy,参考:Ubuntu16.04安装Scrapy命令 都安装成功后,import scrapy也都没出错,但是在终端输入:scrapy 命令时出现错误: Fi ...
- C# JSON帮助类(可互转)
public class JsonHelper { public JsonHelper() { // // TODO: Add constructor logic here // } /// < ...