【问题标题】:UnsafeMutablePointer<Int8> from String in SwiftUnsafeMutablePointer<Int8> 来自 Swift 中的字符串
【发布时间】:2015-03-08 16:42:01
【问题描述】:

我正在使用 Accelerate 框架中 LAPACK 实现中的 dgeev 算法来计算矩阵的特征向量和特征值。遗憾的是,Apple 文档中没有描述 LAPACK 功能,仅包含指向 http://netlib.org/lapack/faq.html 的链接。

如果你查一下,你会发现dgeev中的前两个参数是表示是否计算特征向量的字符。在 Swift 中,它要求UnsafeMutablePointer&lt;Int8&gt;。当我简单地使用"N" 时,我得到一个错误。 dgeev函数和错误描述如下截图

我应该怎么做才能解决这个问题?

【问题讨论】:

    标签: pointers swift char lapack accelerate-framework


    【解决方案1】:

    “问题”是前两个参数被声明为char * 而不是const char *,即使函数没有修改字符串:

    int dgeev_(char *__jobvl, char *__jobvr, ...);
    

    映射到 Swift 为

    func dgeev_(__jobvl: UnsafeMutablePointer<Int8>, __jobvr: UnsafeMutablePointer<Int8>, ...) -> Int32;
    

    一种可能的解决方法是

    let result = "N".withCString { 
        dgeev_(UnsafeMutablePointer($0), UnsafeMutablePointer($0), &N, ...)
    }
    

    在块内部,$0 是一个指向以 NUL 结尾的 char 数组的指针,其中 字符串的 UTF-8 表示形式。


    备注: dgeev_() 不会修改前两个参数指向的字符串, 所以它“应该”声明为

    int dgeev_(const char *__jobvl, const char *__jobvr, ...);
    

    这将被映射到 Swift

    func dgeev_(__jobvl: UnsafePointer<Int8>, __jobvr: UnsafePointer<Int8>, ...) -> Int32;
    

    在这种情况下,您可以简单地将其称为

    let result = dgeev_("N", "N", &N, ...)
    

    因为 Swift 字符串会自动转换为UnsafePointer&lt;Int8&gt;), 如String value to UnsafePointer<UInt8> function parameter behavior 中所述。

    【讨论】:

      【解决方案2】:

      它很丑,但你可以使用:

      let unsafePointerOfN = ("N" as NSString).UTF8String
      var unsafeMutablePointerOfN: UnsafeMutablePointer<Int8> = UnsafeMutablePointer(unsafePointerOfN)
      

      并使用unsafeMutablePointerOfN 作为参数而不是“N”。

      【讨论】:

      • 这个解决方案至少存在一个理论上的问题:.UTF8String 返回的字符串只有在NSString 对象存在时才能保证有效,并且可以立即销毁,因为存在在第一行之后没有提及它。这很可能不会在这里发生,因为这里的字符串是一个字面常量。
      【解决方案3】:

      使用 Swift 4.25,您可以使用这种类似的方法

      let str = "string"
      let unsafePointer = UnsafeMutablePointer<Int8>(mutating: (str as NSString).utf8String)
      

      你可以从unsafePointer得到结果。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-21
        • 1970-01-01
        • 2015-02-27
        相关资源
        最近更新 更多