如何通过引用将UnsafePointer <uint8>传递给C API?

时间:2016-10-06 17:29:14

标签: swift openssl pass-by-reference swift3 unsafe-pointers

我写了一些Swift 2.2代码与OpenSSL C API进行交互,现在我正在尝试将其转换为Swift 3。

在Swift 2中

let octets = pkcs7_d_data(pkcs7_d_sign(receiptPKCS7).memory.contents)
var ptr = UnsafePointer<UInt8>(octets.memory.data)

// now pass pointer by reference
ASN1_get_object(&ptr, &length, &type, &xclass, end - ptr)

在Swift 3中,我不得不进行一些更改

// use guard so i dont have to constantly unwrap these values

guard let octets = pkcs7_d_data(pkcs7_d_sign(receiptPKCS7).pointee.contents),
      var ptr = UnsafePointer<UInt8>(octets.pointee.data) else {
    return nil
}

ASN1_get_object(&ptr, &length, &type, &xclass, end - ptr)
//              ^^^ this is now a compiler error

很遗憾,由于此错误,我无法再通过引用将ptr传递给ASN1_get_object

Cannot pass immutable value as inout argument: Implicit conversion from UnsafePointer<UInt8> to UnsafePointer<UInt8>? requires a temporary

然后其余的错误被切断(没有展开箭头)。

我尝试了什么:

  • ptr作业更改为UnsafePointer<UInt8>(octets.pointee.data)?,但后来我被告知我现有的作业已经会生成一个可选
  • UnsafePointer更改为UnsafeMutablePointer

这里需要改变什么?

1 个答案:

答案 0 :(得分:3)

问题似乎是octets.pointee.data是一个问题 UnsafeMutablePointer<UInt8>!,但ASN1_get_object期待 UnsafePointer<UInt8>?

的地址

以下代码编译,但我无法测试它:

if
    let octets = pkcs7_d_data(pkcs7_d_sign(receiptPKCS7).pointee.contents),
    let data = octets.pointee.data {

    var ptr: UnsafePointer? = UnsafePointer(data) // (*)
    var length = 0
    var tag: Int32 = 0
    var xclass: Int32 = 0

    ASN1_get_object(&ptr, &length, &tag, &xclass, Int(octets.pointee.length))
}

(*)是指针转换,使其编译。