【问题标题】:Swift - C API bridge - how to handle null pointersSwift - C API 桥 - 如何处理空指针
【发布时间】:2017-11-19 09:01:59
【问题描述】:

在 Swift 中,我使用的是 C API,它返回带有 char 数组的结构(包含 UTF8 以 null 结尾的字符串或 null)。

struct TextStruct {
   char * text;
   //other data
}

我用:

let text: String = String(cString: data.text)

但是,当 data.textnullptr 时,此方法会失败,并显示

fatal error: unexpectedly found nil while unwrapping an Optional value

是否有任何解决方法,或者我必须在使用cString ctor 之前手动检查data.text

【问题讨论】:

    标签: c swift optional


    【解决方案1】:

    除了Gwendal Roué's solution:还可以 注释 C API 以指示指针是否可以为空。 例如,

    struct TextStruct {
        char * _Nullable text;
        //other data
    };
    

    被导入到 Swift 中

    public struct TextStruct {
        public var text: UnsafeMutablePointer<Int8>?
        // ...
    }
    

    其中var text 是“强”可选而不是隐式 展开可选。那么

    let text = String(cString: data.text)
    // value of optional type 'UnsafeMutablePointer<Int8>?' not unwrapped; ...
    

    不再编译,并强制您使用可选绑定或 其他展开技术,以及 “致命错误:意外发现 nil” 不会再意外发生了。

    有关更多信息,请参阅 Swift 博客中的"Nullability and Objective-C" – 尽管有标题,但它也可以与纯 C 一起使用。

    【讨论】:

    • 我认为遵循这种方法会更安全:)
    【解决方案2】:

    是的,您必须检查 data.text,以确保它可以提供 String(cString:) 初始化程序,即 documented 需要非空指针

    一种技术是使用if let 语句。这是一种安全地展开可选值的经典技术:

    let str: String?
    if let ptr = ptr {
        str = String(cString: ptr)
    } else {
        str = nil
    }
    print("got \(str ?? "nil")")
    

    另一种技术是Optional.map 函数:

    let str = ptr.map { String(cString: $0) }
    print("got \(str ?? "nil")")
    

    【讨论】:

    • char * text; 被导入到 Swift 作为隐式展开的可选 UnsafeMutablePointer&lt;Int8&gt;!。为了使用 Optional.map 你必须先将它分配给一个强可选。
    【解决方案3】:

    可以检查指针的地址是否设置

    let textIsSet = Int(bitPattern: data.text) != 0
    
    let text: String? = textIsSet ? String(cString: data.text) : nil
    

    【讨论】:

      猜你喜欢
      • 2016-03-14
      • 1970-01-01
      • 2011-09-25
      • 2021-10-17
      • 2021-11-08
      • 2014-01-15
      • 2021-02-01
      • 2012-02-17
      相关资源
      最近更新 更多