挙動

2016-08-24 4 views
0

私はスウィフトにAES 128を実装しようと、最近CChar配列にスウィフト文字列を書き込むことで問題に遭遇しています:32ビットデバイスでは挙動

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) 

(アプリ2は、アプリ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と同じ問題に遭遇:32ビットデバイスで

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

これは、64ビットデバイスのログ0x00007f853c123760ながら0x7a992094を記録します。

すべてのアーキテクチャでgetCStringまたはwithCStringの結果を同じにするにはどうすればよいですか?これは、サイズがCCharであるか、または異なるアーキテクチャのアレイで問題になっていますか?

答えて

1

悪い点はstrideof(keyPtr.dynamicType) strideof(Array<CChar>)と同じで、値は32ビットで4、64ビットで8です。

あなたはこのようなあなたのコードを変更する必要があります:あなたはおよそwithCString()を尋ねたことから、完全を期すために

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

のメソッド呼び出しは、一時的C文字列表現 (すなわちNULを作成しますCCharの末尾のシーケンス)が Swift文字列であり、その文字列の (最初の文字の)に設定された$0のクロージャを呼び出します。したがって$0ポインタ であり、プラットフォームによっては32ビットまたは64ビットです。

そして、あなたが与えられた配列にそのC文字列をコピーすることができます、かなり確信して、これはそれが

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

ありがとうマーティン、私はいつあなたが出現するのだろうかと思っていた;) – JAL

+0

これは、なぜ 'withCString'を' getCString'に推奨するのでしょうか?私はコードレビューの[あなたの答えの1つ](http://codereview.stackexchange.com/a/135430/73433)から覚えています。 – JAL

+1

@ JAL:これはcStringUsingEncodingについてですが、getCStringではなく、これらのメソッドのいずれも問題ありません。 –