Swift4.1 swift 和 C 的交互

C语言基本类型对应表

其中有三个是特殊的

  • wchar_t - CWideChar
  • char16_t - CChar16
  • char32_t - CChar32
    其他的都是首字母加上 C 然后采用驼峰式命名方法进行命名



一、基本类型在Swift中如何引用

  • 1、创建C语言类型
let cInt: CInt = 2
let cChar: CChar = 49


  • 2、引用C语言类型
.h
const int global_ten;



.m
const int global_ten = 10;

在Swift中使用

let _ = global_ten


  • 3、NS_STRING_ENUMNS_EXTENSIBLE_STRING_ENUM

NS_STRING_ENUM 通常表示值固定
NS_EXTENSIBLE_STRING_ENUM 表示可扩展

.h
// NS_STRING_ENUM 通常表示值固定
typedef NSString * PQButtonColor NS_STRING_ENUM;

PQButtonColor const PQButtonColorRed;
PQButtonColor const PQButtonColorGreen;
PQButtonColor const PQButtonColorBlue;

// NS_EXTENSIBLE_STRING_ENUM 表示可扩展
typedef int Shape NS_EXTENSIBLE_STRING_ENUM;

Shape const ShapeCircle;
Shape const ShapeTriangle;
Shape const ShapeSquare;



.m

PQButtonColor const PQButtonColorRed = @"Red";
PQButtonColor const PQButtonColorGreen = @"Green";
PQButtonColor const PQButtonColorBlue = @"Blue";



Shape const ShapeCircle = 1;
Shape const ShapeTriangle = 2;
Shape const ShapeSquare = 3; 



使用NS_STRING_ENUM修饰的在swift中生成一个类型与下面的struct
会把前缀忽略掉

struct PQButtonColor: RawRepresentable {
    typealias RawValue = String
    
    init(rawValue: Self.RawValue)
    var rawValue: RawValue { get }
    
    static var red: PQButtonColor { get }
    static var green: PQButtonColor { get }
    static var blue: PQButtonColor { get }
}

swift


extension PQButtonColor{
    static var pink: PQButtonColor {
        return PQButtonColor(rawValue: "Pink")
    }
}

let bColor: PQButtonColor = .red
let bColorString = bColor.rawValue // red


extension Shape {
    static  var ellise: Shape{
        return Shape(4)
    }
}

let ellist: Shape = .ellise

两种都可以进行扩展。


二、简单方法在Swift中如何引用



  • 1、固定参数的方法

定义

int add(int a, int b);

int add(int a, int b){
    return a + b;
}

使用

//方法
let sumNum = add(30, 30)

let num1 = 20
// 这里必要要转化为CInt类型
let sumNum1 = add(Int32(num1), 2)
  • 2、不固定参数的方法
int vsum(int count, va_list numbers);
int sum(int count, ...);


int vsum(int count, va_list numbers){
    int i = 0, sum = 0;
    while (i < count) {
        sum += va_arg(numbers, int);
        ++i;
    }
    return sum;
}
int sum(int count, ...){
    int sum = 0;
    va_list ap;
    va_start(ap, count);
    sum = vsum(count, ap);
    return sum;
}



使用

在swift中只能使用vsum这个函数,并不可以使用sum这个函数,因为其不支持...

没有sum这个方法


// 使用方法1  需要注意的是 count和数组的元素个数要保持一致
let _ = vsum(7, getVaList([1,2,3,4,56,7,8]))

// 使用方法2
let _ = withVaList([1,2,3]){
    vsum(3, $0)
}


三、简单Struct和union在Swift中如何引用



  • 1、struct

定义

typedef struct Location{
    int x,y;
};

上面代码会在Swift中生成一个struct

struct Location {
    var x: CInt
    var y: CInt
}

使用

var loc = Location(x: 0, y: 0);


  • 2、为struct添加方法
Location moveX(Location loc, int delta);
Location moveY(Location loc, int delta);

.m
Location moveX(Location loc,int delta){
    loc.x += delta;
    return loc;
}

Location moveY(Location loc,int delta){
    loc.y += delta;
    return loc;
}

使用

loc = moveY(loc, 5)

但是在Swift中是不提倡用这种方式去改变的,应该是用loc.moveX()这样子的方式去调用
如果想达到这种效果,就要是使用CF_SWIFT_NAME
moveX为例

// 使用CF_SWIFT_NAME修饰这个方法,把name变成签名 
Location moveX(Location loc, int delta) CF_SWIFT_NAME(Location.moveX(self:delta:));

然后就可以在Swift中这样子调用了

loc = loc.moveX(delta: 5)



通常我还会为struct提供一个工厂方法,在Swift中我们也应该是Location.init去创建,而不是通过一个全局函数去创建

//工厂方法的创建
Location createLocation(int) CF_SWIFT_NAME(Location.init(xy:));

.m

Location createLocation(int xy){
    Location loc = { .x = xy, .y = xy };
    return loc;
}

使用如下:

//工厂方法
let _ = Location(xy: 3)



接下来在给struct添加一个getOriginsetOrigin方法

//getter
Location getOrigin(void) CF_SWIFT_NAME(getter:Location.origin());
//setter
Location setOrigin(Location) CF_SWIFT_NAME(setter:Location.origin(newOrigin:));

Location origin = { .x = 0, .y = 0 };
Location getOrigin(){
    return origin;
}

Location setOrigin(Location newOrigin){
    origin = newOrigin;
    return origin;
}

使用如下:

// get set
Location.origin.y = 10
let _ = Location.origin.x


union

由于Swift并不支持union,所以会在转化的时候变成一个struct

比如定义一个如下的 union

typedef union {
    char character;
    int code;
} ASCII;

在Swift中会转化成为

/*
struct ASCII{
    var character: Int8
    var code: CInt
    
    init(character: Int8)
    init(code: CInt)
}
 */

使用如下:

let c = ASCII(character: 77)

然后我们看一个稍微复杂一点点的

// struct and union
typedef struct {
    union {
        char model;
        int series;
    };
    
    struct {
        double pricing;
        bool isAvailable;
    }info;
    
} Car;

使用如下:

let car = Car.init(.init(series: 50), info: .init(pricing: 100, isAvailable: true))
print(car.series)

在匿名的union中,可以直接调用里面的变量,就像这个对象不存在一样。


三、enum在Swift中如何引用



1、申明一个enum

typedef enum {
    BMW,AUDI,BENZ
}CarType;

使用

let _ = BMW
let _ = AUDI
let _ = AUDI

这个和我们想象的有差别,不应该是CarType.BMW这样子的形式吗?之所以不是是因为会转化为如下代码

/*
struct CarType: RawRepresentable, Equatable {}
var BMW: CarType { get }
var AUDI: CarType { get }
var BENZ: CarType { get }
 */

如果像变成Swift中的样子,要使用NS_ENUM(...)
里面有两个参数:

  • 第一个参数是类型
  • 第二个是enum名称

定义和使用

typedef NS_ENUM(int,PQCarType) {
    PQBMW,PQAUDI,PQBENZ
};

let bmw: PQCarType = .PQBMW


Demo 地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,695评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,569评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,130评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,648评论 1 297
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,655评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,268评论 1 309
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,835评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,740评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,286评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,375评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,505评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,185评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,873评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,357评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,466评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,921评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,515评论 2 359

推荐阅读更多精彩内容