行为

2016-08-24 22 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,但这些方法中的任何一个都没问题。 –