行爲

2016-08-24 43 views
0

我想在斯威夫特實現AES 128和最近碰到了一個問題,寫斯威夫特字符串到CChar陣列:行爲

let testString = "myTestString" 

var keyPtr = [CChar](count: kCCKeySizeAES128 + 1, repeatedValue: 0) 
bzero(&keyPtr, strideof(keyPtr.dynamicType)) 
testString.getCString(&keyPtr, maxLength: strideof(keyPtr.dynamicType), encoding: NSUTF8StringEncoding) 
print(keyPtr) 

在32位器件( iPad 2的,iPad的4)此記錄:

[109, 121, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 

而在64位的設備(iPhone 6,MacBook Pro的I7)此日誌:

[109, 121, 84, 101, 115, 116, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 

64位的情況是正確的結果,而32位的結果不是。

我遇到同樣的問題與withCString,以及:

testString.withCString({ 
    print($0) 
}) 

在32位的設備本記錄0x7a992094而一個64位的設備日誌0x00007f853c123760

如何在所有體系結構中使getCStringwithCString的結果相同?這是否與CChar或不同架構上的陣列大小有關?

回答

1

壞處是這樣的:strideof(keyPtr.dynamicType) 它和strideof(Array<CChar>)一樣,它的值是4位32位,64位是8位。

您需要修改你這樣的代碼:

bzero(&keyPtr, keyPtr.count) //<-this is not needed, as you are specifying `0` for `repeatedValue`. 
testString.getCString(&keyPtr, maxLength: keyPtr.count, encoding: NSUTF8StringEncoding) 
+0

是的,很肯定這是它。 'withCString'把我扔掉了,因爲我正在打印內存位置,而不是那個內存中的內容。再次感謝。 – JAL

1

爲了完整起見,因爲你問起withCString()

這個方法調用創建一個臨時的C字符串表示 (即NUL - 終止順序CChar)的 Swift字符串,並調用$0設置爲該字符串中的地址 (第一個字符)的閉包。因此,$0指針 因此取決於平臺,因此是32位或64位。

而且你可以在C字符串複製到指定的數組:

testString.withCString { strlcpy(&keyPtr, $0, keyPtr.count) } 
+0

感謝Martin,我想知道你什麼時候會出現;) – JAL

+0

這就是爲什麼你推薦'withCString' over'getCString'?我記得在Code Review上[你的答案之一](http://codereview.stackexchange.com/a/135430/73433)。 – JAL

+1

@JAL:這是關於cStringUsingEncoding,而不是getCString,但這些方法中的任何一個都沒問題。 –