2016-10-06 38 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