2016-10-06 37 views
3

我写了一些雨燕2.2的代码与OpenSSLçAPI的互动,现在我想将其转换为斯威夫特3.如何通过引用将UnsafePointer <UInt8>传递给C API?

在斯威夫特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) 

在斯威夫特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 

不幸的是,我可以参考不再传递ptrASN1_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)?但后来有人告诉我,我现有的分配已经产生可选
  • 改变了UnsafePointerUnsafeMutablePointer

这里需要改变什么?

+0

我还没有使用Swift 3,但我前两天在2.3中处理过类似的问题。直接执行'ASN1_get_object(&octet.pointee.data ...)'没有做你需要的吗? –

+0

首先,它仍然抛出一个关于不传入不可变的错误,其次我想在移动'ptr'时保留一个单独的引用。 – ray

回答

3

这个问题似乎是octets.pointee.dataUnsafeMutablePointer<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)) 
} 

(*)是指针转换这使得编译。

+0

这似乎工作,但我没有失去任何东西,没有指定'UInt8'?当它处于“警戒”状态时,我也不能指定'ptr',所以现在我每次使用它时都必须打开它。 – ray

+0

@ray:'ptr'的类型为'UnsafePointer ?',你可以通过点击Xcode中的变量来验证。 'UInt8'是自动推断的,你可以更详细地写'var ptr:UnsafePointer ? = UnsafePointer (data)'。 - 你不能在警戒声明后面定义'ptr' *吗? –

+0

我可以,我只是因为我似乎无法分配指针**和**指定它是可选的,如果它是条件的一部分这一事实而感到难过。一旦我在'guard'之外定义它,每次使用它时都必须打开'ptr'。 – ray