Swift中对C语言接口缓存的使用以及数组、字符串转为指针类型的方法

由于Swift编程语言属于上层编程语言,而Swift中由于为了低层的高性能计算接口,所以往往需要C语言中的指针类型,由此,在Swift编程语言刚诞生的时候就有了UnsafePointer与UnsafeMutablePointer类型,分别对应为const Type*类型与Type *类型。

而在Swift编程语言中,由于一般数组(Array)对象都无法直接用于C语言中含有指针类型的函数参数(比如:void*),所以往往需要将数组转为指针类型,此外也需要将数组中元素内容存放到连续的存储空间。此外,Swift中的字符串对象都是String结构体对象,因此也需要将它们转换为C语言中const char *类型相兼容的类型,因此这里将给大家介绍一些比较简便、且纯Swift接口的使用方法,而不是借助于Objective-C的Foundation库。

/**
 此函数用于将一个数组(Array)的首个元素的值做加1操作
 - parameters:
    - p: inout [Int]类型,传入的数组对象首地址
 - returns: Void
*/
func test(inout p: [Int]) {
    p[0] += 1
}

class ViewController: NSViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        var a = 0

        // 下面使用UnsafeMutablePointer自带的alloc类方法分配10个Int元素的存储空间
        // 这个方法其实应该就是对malloc函数的封装了,用于外部的C接口十分有用
        let buf = UnsafeMutablePointer<Int>.alloc(10)
        let dst = UnsafeMutablePointer<Int>.alloc(10)

        // 分别对buf与dst存储空间进行初始化赋值
        for i in 0 ..< 10 {
            buf[i] = i
            dst[i] = 0
        }

        // 使用assignBackwardFrom将buf存储空间中后5个元素拷贝到dst存储空间的前5个元素中
        dst.assignBackwardFrom(buf.advancedBy(5), count: 5)

        // 用Array分配一个10个Int元素的数组对象arr
        var arr = [Int](count: 10, repeatedValue: 0)

        // 将dst中的所有元素拷贝到arr中
        for i in 0 ..< 10 {
            arr[i] = dst[i]
        }
        print(arr)

        // 释放buf与dst。注意,这里必须用dealloc来释放,且里面的参数也要与alloc的参数对应!
        // 不释放会引发内存泄漏
        buf.dealloc(10)
        dst.dealloc(10)

        // arr数组对象指向另一个[1, 2, 3]数组字面量构成的Array对象
        arr = [1, 2, 3]

        // 调用test函数,使得arr的第一个元素的值加1
        test(&arr)
        print("arr = \(arr)")

        // 这里使用Array的withUnsafeMutableBufferPointer方法将数组元素内容转为
        // 指向一个连续存储空间的首地址。
        // 所以p的类型为:UnsafeMutablePointer<Int>
        let p = arr.withUnsafeMutableBufferPointer() {
            // 这里,形参是一个含有一个UnsafeMutableBufferPointer的形参,
            // 返回类型为UnsafeMutablePointer的函数类型。
            (inout buffer: UnsafeMutableBufferPointer<Int>) -> UnsafeMutablePointer<Int> in
            return buffer.baseAddress
        }

        a = 0

        // 我们先查看原先数组对象中的元素内容
        for i in 0 ..< 3 {
            a += p[i]
        }
        print("a = \(a)")

        // 我们通过p指针对象对数组arr的内容进行修改
        p[0] -= 1
        p[1] += 1
        p[2] += 2

        // 然后打印出修改后的arr数组对象中的元素内容
        print("arr is: \(arr)")

        // 这里用nulTerminatedUTF8方法先转为ContiguousArray<CodeUnit>对象类型,
        // 其中,CodeUnit是UInt8类型。
        // 然后用withUnsafeBufferPointer转为UnsafePointer<CChar>类型
        let cstr = "abcd".nulTerminatedUTF8.withUnsafeBufferPointer() {
            return UnsafePointer<CChar>($0.baseAddress)
        }

        // 这里再将刚才生成的UnsafePointer<CChar>类型的C格式字符串转回String对象
        let string = String.fromCString(cstr)!
        print("string is: \(string)")
    }
}

上述代码中,UnsafeMutablePointer的alloc方法也是个很不错的方法,这个方法应该是直接对C语言标准库malloc的封装,可以使得我们方便地在Swift中分配连续的存储空间,比如对于像图像处理、矩阵计算等算法尤为实用。当然,如果我们的逻辑主要用Array来处理,然后再交给底层的C语言接口做高性能计算,那么也可以使用数组对象转连续存储空间withUnsafeBufferPointer方法,这种处理方式在网络数据通信中也比较实用。

时间: 2024-10-22 16:37:33

Swift中对C语言接口缓存的使用以及数组、字符串转为指针类型的方法的相关文章

【转】C#语言之“string格式的日期时间字符串转为DateTime类型”的方法

方法一:Convert.ToDateTime(string) string格式有要求,必须是yyyy-MM-dd hh:mm:ss ================================================ 方法二:Convert.ToDateTime(string, IFormatProvider) DateTime dt; DateTimeFormatInfo dtFormat = new System.GlobalizationDateTimeFormatInfo()

C#语言之“string格式的日期时间字符串转为DateTime类型”的方法

方法一:Convert.ToDateTime(string) string格式有要求,必须是yyyy-MM-dd hh:mm:ss ================================================ 方法二:Convert.ToDateTime(string, IFormatProvider) DateTime dt; DateTimeFormatInfo dtFormat = new System.GlobalizationDateTimeFormatInfo()

苹果新的编程语言 Swift 语言进阶(四)--字符串和收集类型

一.字符串( String  )和字符类型(Character) 字符串是一种字符的带次序的收集类型(相当于数组),字符是字符串中的元素. 在Swift 语言中,字符串是编码独立的Unicode字符的组合,并提供相应方法来获取以各种Unicode呈现方式包含的字符. 1. 字符串定义和初始化 Swift 语言使用var或let关键字来定义一个常量字符串(不可修改)或变量字符串(可以修改).  而不是像Object C语言一样定义两种不同的类型. Swift 语言允许使用一个双引号的字符串来初始化

swift中通知的使用方法

其实swift语言和OC语言,在本质上都是一样,其里面的方法之类的也基本相同.通知的使用方法也是一样,只是代码的书写格式发生了改变而已.下面我通过一个简单的小需求,也讲一讲通知,用swift中的闭包,也能完成此功能. 使用通知需要注意事项: 1,先确保接收中心存在,在设置通知中心. 2,最后一定要移除通知中心. 3,通知也是可以传值的,放在userInfo里面. 具体界面效果,我在这里就不截图了,希望各位开发者,自己写一遍,然后运行. ViewController // //  ViewCont

swift学习笔记-----swift中的指针

swift语言为了简化,把指针隐形化了.没有像OC中那样的" * ".把底层的问题交给C语言去处理,我们可以在swift中调用C 语言来解决.当然,OC也是可以调用的. 但是在某些场景下,这种调用可能不是很方便.比如,基于字节流的解析中,这时我们所接受的数据是要进行解析,可能用到指针.如果在C中去调用,当然也是可以的.但如果想写的简洁一些,用swift直接去处理这些,是否可以呢.那就要看在swift中是否很好的去使用指针呢. 事实上,swift是支持使用指针的.苹果已经公开了swift

在 Swift 中实现 NS_OPTIONS

从Xcode 4.5以后,我们在Objective-C中使用NS_ENUM和NS_OPTIONS来定义一个枚举,以替代C语言枚举的定义方式.其中NS_ENUM用于定义普通的枚举,NS_OPTIONS用于定义选项类型的枚举. 而到了Swift中,枚举增加了更多的特性.它可以包含原始类型(不再局限于整型)以及相关值.正是由于这些原因,枚举在Swift中得到了更广泛的应用.在Foundation中,Objective-C中的NS_ENUM类型的枚举,都会自动转换成Swift中enum,并且更加精炼.以

SWIG 多语言接口变换 【转】

一.             SWIG 是Simple Wrapper and Interface Generator的缩写,是一个帮助使用C或者C++编写的软件创建其他编语言的API的工具.例如,我想要为一个C++编写的程序创建.NET API,一般情况下我必须使用托管C++(Managed C++)去编写大量的代码才能生成它的.NET API.有了SWIG,这个机械的工作将变得非常简单.你只须要使用一个接口文件告诉SWIG要为那些类创建.NET API,SWIG就会自动帮你生成它的.NET

swift 中的defer

defer是swift中重要的语言特性,主要的作用是延迟执行以及在return之前执行. 1.延迟执行: 应用场景: 2.return之前执行:defer代码必须在return之前,比如在打开文件后需要关闭文件,防止出现没关闭文件就直接被return了 应用场景: 原文地址:https://www.cnblogs.com/IT-DavidYang/p/8514522.html

python调用C语言接口

python调用C语言接口 注:本文所有示例介绍基于linux平台 *** 在底层开发中,一般是使用C或者C++,但是有时候为了开发效率或者在写测试脚本的时候,会经常使用到python,所以这就涉及到一个问题,用C/C++写的底层库,怎么样直接被python来调用? python作为一门胶水语言,当然有办法来处理这个问题,python提供的方案就是ctypes库. ctypes ctypes是python的外部函数库,它提供了C语言的兼容类型,而且可以直接调用用C语言封装的动态库. 如果各位有较