zoukankan      html  css  js  c++  java
  • 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方法,这种处理方式在网络数据通信中也比较实用。

  • 相关阅读:
    第3章 Spring AOP
    第2章 Spring中的Bean
    第1章 Spring的应用
    Codeforces Round #558 (Div. 2)-Cat Party (Hard Edition)-(前缀和 + 模拟)
    Codeforces Round #552 (Div. 3)-1154E-Two Teams-(模拟+双指针)
    Codeforces Round #552 (Div. 3)-D-Walking Robot-(贪心)
    Codeforces Round #552 (Div. 3)-C-Gourmet Cat
    Codeforces Round #555 (Div. 3)
    2019年湘潭大学程序设计竞赛(重现赛)
    Buy Fruits-(构造)
  • 原文地址:https://www.cnblogs.com/zenny-chen/p/5618485.html
Copyright © 2011-2022 走看看