【问题标题】:Converting array of C strings to Swift string array将 C 字符串数组转换为 Swift 字符串数组
【发布时间】:2016-11-20 05:32:54
【问题描述】:

在 Swift 3 中,带有签名 const char *f() 的 C 函数在导入时映射到 UnsafePointer<Int8>! f()。它的结果可以转换为 Swift 字符串:

let swiftString = String(cString: f())

问题是,如何将一个以 NULL 结尾的 C 字符串数组映射到 Swift 字符串数组?

原始C签名:

const char **f()

导入的 Swift 签名:

UnsafeMutablePointer<UnsafePointer<Int8>?>! f()

Swift 字符串数组:

let stringArray: [String] = ???

【问题讨论】:

    标签: arrays swift pointers type-conversion swift3


    【解决方案1】:

    据我所知,没有内置方法。 您必须遍历返回的指针数组,将 C 字符串转换为 Swift Strings,直到找到 nil 指针:

    if var ptr = f() {
        var strings: [String] = []
        while let s = ptr.pointee {
            strings.append(String(cString: s))
            ptr += 1
        }
        // Now p.pointee == nil.
    
        print(strings)
    }
    

    备注: Swift 3 使用可选指针来表示可以是nil 的指针。 在您的情况下,f() 返回一个隐式展开的可选,因为 头文件未“审核”:编译器不知道是否 该函数可以返回NULL,也可以不返回。

    使用“可空性注释”,您可以提供该信息 到 Swift 编译器:

    const char * _Nullable * _Nullable f(void);
    // Imported to Swift  as
    public func f() -> UnsafeMutablePointer<UnsafePointer<Int8>?>?
    

    如果函数可以返回NULL,则

    const char * _Nullable * _Nonnull f(void);
    // Imported to Swift  as
    public func f() -> UnsafeMutablePointer<UnsafePointer<Int8>?>
    

    如果f() 保证返回非NULL 结果。

    有关可空性注释的更多信息,请参阅示例 Nullability and Objective-C 在 Swift 博客中。

    【讨论】:

    • ... 和支持“true”String 类型的其他语言(包括 C++)需要非常相似的技术。这些“其他”语言中的每一种都为每个字符串值维护一个单独的“长度”:它们不依赖于终止空字节。但是,它们都有专门用于处理它们的方法。 (而且,通常,它们在存储的当前值的末尾保留一个已知 NULL 字节。)
    • ... 和 ... "meh" ... 每当谈到数字计算机时,我“从不说‘从不’。”如果是指针,它可能是 @987654333 @。 f() 中任何未来产生此返回值的 *bug 都会发展成一个非常 令人讨厌且难以定位的错误,可能会浪费数小时来减少微秒的时间。我是一个非常保守的程序员...
    • @MikeRobinson:我没有将这句话添加到“shave microseconds”,而是直接关注可空性注释。当然,可以讨论是否应在每次调用时检查记录返回有效指针的 API 的返回值,或者是否应将其视为编程错误并应提前崩溃。跨度>
    • ...马丁,我确实没有专门针对您发表过该评论。如果您有其他解释,我深表歉意,我可以一定要看看你可能有。我想我并没有过多地考虑“好的、记录在案的 API”,而是“在这个遗留应用程序中的其他地方编写代码,我们都以某种方式谋生支持”。但是,我清楚地重新读到您无疑在谈论“API 等”。因此,我的 cmets 可能(在您的预期上下文中)脱节了,为此我公开道歉。
    • 在 Swift 3 中,我不得不将 ptr += 1 更改为 ptr = ptr.advanced(by: 1)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-13
    • 2015-10-11
    • 2017-11-27
    • 1970-01-01
    相关资源
    最近更新 更多