Swift 3.0中C语言指针类型在Swift编程语言中如何 *** 作

Swift 3.0中C语言指针类型在Swift编程语言中如何 *** 作,第1张

概述Swift 3.0在2.0基础上做了许多改动,其中之一就是与C API的兼容性上。这里我将主要讲解一下C语言的指针与Swift编程语言的桥接在Swift 3.0中改成啥样了。 首先,为了Swift编程语言语法体系的统一性,Swift语言核心设计团队为所有诸如UnsafePointer、UnsafeMutablePointer等类型增加了Optional,这个在Swift 2.x中是没有的,不过你可

Swift 3.0在2.0基础上做了许多改动,其中之一就是与C API的兼容性上。这里我将主要讲解一下C语言的指针与Swift编程语言的桥接在Swift 3.0中改成啥样了。


首先,为了Swift编程语言语法体系的统一性,Swift语言核心设计团队为所有诸如UnsafePointer、UnsafeMutablePointer等类型增加了Optional,这个在Swift 2.x中是没有的,不过你可以直接对一个UnsafePointer<Int32>类型的对象置空。而在3.0版本中增加了这些类型的Optional属性之后,我们就可以把它们作为其他类型一样去对待了。

然后,Swift 3.0给voID*和const voID*分别引入了UnsafeRawPointer类型和UnsafeMutableRawPointer类型。而在Swift 2.x中,它们分别对应的是UnsafePointer<VoID>与UnsafeMutablePointer<VoID>。此外,UnsafeRawPointer类型与UnsafeMutableRawPointer类型不能直接通过UnsafePointer与UnsafeMutablePointer的构造器转换为相应类型,而只能通过它们的assumingMemoryBound(to:)方法去转。

最后,UnsafePointer类型要转为UnsafeMutablePointer类型时现在必须使用UnsafeMutablePointer的init(mutating:)方法,这里增加了一个参数标签mutating。


下面我们将通过一段代码来呈现以上说的这三点。以下有3个代码片段,分别是一个头文件、一个C源文件和一个Swift源文件。

头文件内容:

extern voID* _Nonnull GenerateData(voID);extern voID UseData(const int* _Nonnull pData);extern const voID* _Nullable GenerateData2(voID);extern voID UseData2(int* _Nullable pData);

C源文件内容:

#include <stdio.h>static int sData = 10;voID* GenerateData(voID){    return &sData;}voID UseData(const int *pData){    printf("The data is: %d\n",*pData);}const voID* _Nullable GenerateData2(voID){    return &sData;}voID UseData2(int *pData){    if(pData != NulL)        printf("The data is: %d\n",pData[0]);}


Swift源文件内容:

class VIEwController: NSVIEwController {     overrIDe func vIEwDIDLoad() {        super.vIEwDIDLoad()                let dataPtr = GenerateData()                // 这里可以看到,dataPtr的类型是UnsafeMutableRawPointer        print("dataPtr type is: \(type(of: dataPtr))")                // 这里先将dataPtr类型转换为UnsafeMutablePointer<Int32>类型        let dataInt32Ptr = dataPtr.assumingMemoryBound(to: type(of: Int32()))                print("dataInt32Ptr type is: \(type(of: dataInt32Ptr))")                // 我们还可以对指针所指向的整型数据做些修改        dataInt32Ptr.pointee += 10                // 在传递UseData的实参时,需要将dataInt32Ptr的类型再转为UnsafePointer<Int32>        UseData(UnsafePointer<Int32>(dataInt32Ptr))                // 这里dataPtr2是UnsafeRawPointer?类型        let dataPtr2 = GenerateData2()                // 这里dataInt32Ptr2的类型是UnsafePointer<Int32>?        let dataInt32Ptr2 = dataPtr2?.assumingMemoryBound(to: type(of: Int32()))                // 这里需要将dataInt32Ptr2类型转换为UnsafeMutablePointer<Int32>        UseData2(UnsafeMutablePointer<Int32>(mutating: dataInt32Ptr2))                var intObj: Int32 = 0                // 这里可以看到,在Swift中的一个Int32类型对象,        // 对它取地址 *** 作也可以与UnsafePointer<Int32>类型进行匹配        UseData(&intObj)                UseData2(&intObj)                var uintObj: UInt = 1                // 如果要将一个UnsafePointer<UInt>转换为UnsafePointer<Int32>,        // 现在无法直接用UnsafePointer的构造方法进行转换。        // 为了看清整个转换过程,我们先用withUnsafePointer来获取uintObj的指针类型对象        let uintPtr = withUnsafePointer(to: &uintObj) {            (ptr: UnsafePointer<UInt>) -> UnsafePointer<UInt> in            return ptr        }                // 这里使用了Swift 3新引入的UnsafePointer与UnsafeMutablePointer的        // withMemoryRebound(to:capacity:_:)方法显式地将当前指针的原始类型        // 转换为目标类型的指针对象。        // 这里的Int32.self相当于type(of: Int32()),获取到的是Int32元类型        UseData(uintPtr.withMemoryRebound(to: Int32.self,capacity: 1) {            (ptr: UnsafePointer<Int32>) -> UnsafePointer<Int32> in            return ptr        })                // 为了看清下一步 *** 作,我们这里将withMemoryRebound方法所返回的        // UnsafePointer<Int32>对象hold住        let constPtr = uintPtr.withMemoryRebound(to: Int32.self,capacity: 1) {            (ptr: UnsafePointer<Int32>) -> UnsafePointer<Int32> in            return ptr        }    }}

上述代码详细介绍了如何通过C语言函数接口获得一个指针类型,然后做相互转换。此外,还有在Swift中定义的对象如何作为指针类型的参数传入C语言函数中。这里涉及到了Swift 3.0中的新方法,包括UnsafeRawPointer与UnsafeMutableRawPointer的assumingMemoryBound(to:)方法;UnsafePointer与UnsafeMutablePointer的withMemoryRebound(to:capacity:_:)方法。Swift 3.0中取消了UnsafePointer与UnsafeMutablePointer构造方法对任意类型的指针进行转换的实现,取而代之的是,对于指针转换的数据类型都一致的情况,可以通过UnsafeMutablePointer中的init(mutating:)方法将UnsafePointer转换UnsafeMutablePointer;而UnsafePointer可直接使用init(_:)将UnsafeMutablePointer转换相应类型的UnsafePointer类型。除此之外,非相应数据类型的指针转换都必须使用withMemoryRebound(to:capacity:_:)方法。

各位可以在Xcode 8上尝试运行。

总结

以上是内存溢出为你收集整理的Swift 3.0中C语言指针类型在Swift编程语言中如何 *** 作全部内容,希望文章能够帮你解决Swift 3.0中C语言指针类型在Swift编程语言中如何 *** 作所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1069165.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存