我试图在Apple Swift中实现一些AES256加密例程,以便在ObjC,C和Swift代码和数据类型之间实现互操作性,并且遇到了一些问题,我希望有人对某些事情提出一些建议我被忽视了.
正如大多数人所熟悉的那样,常见的C风格模式是声明一个未初始化的指针然后将其传递给一个函数,其中函数调用malloc()是一个对象并指向它的指针; 函数调用完成后,指针指向新创建的对象.Common Crypto库在某些地方使用它; 最值得注意的是,当创建一个新的CCCryptor对象(实际上是一个幕后的结构,看起来像是对CCCryptorRef的typedef'ed一个不透明的引用) - 调用CCCryptorCreate()的最后一个参数是这样一个指针,应该在函数调用的结论,包含一个指向CCCryptorRef的指针.
Swift给这个带来了皱纹 - 变量不能是未初始化的,它们总是有一个值或者是nil(/可选),因此我在这里碰到了一点点.以下不起作用,因为CCCryptorCreate(正确地)就好像我只是传递nil作为最后一个参数,我是:
var myCryptorRef: CMutablePointer<Unmanaged<CCCryptorRef>?> = nil
CCCryptorCreate(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES128),
CCOptions(kCCOptionECBMode), seedData.bytes(), UInt(kCCKeySizeAES256),
nil, myCryptorRef)
Run Code Online (Sandbox Code Playgroud)
但你也不能将它声明为可选项,如下所示:
var myCryptorRef: CMutablePointer<Unmanaged<CCCryptorRef>?>?
Run Code Online (Sandbox Code Playgroud)
或者作为非指针类型:
var myCryptoRef: Unmanaged<CCCryptorRef>?
CCCryptorCreate(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES128),
CCOptions(kCCOptionECBMode), seedData.bytes(), UInt(kCCKeySizeAES256),
nil, &myCryptorRef)
Run Code Online (Sandbox Code Playgroud)
由于CCCryptorCreate所期望的是指向CCCryptorRef的未初始化指针或者已经是malloc()的ed CCCryptorRef,尝试传递它尚未初始化的对象的地址并不像您期望的那样好.
所以,它归结为:任何人都可以在调用CCCryptorCreate之前想出一种初始化CCCryptor结构的方法(通过命名struct中的所有变量似乎不起作用的结构init的Swift标准方法),或者一些替代构造,这将允许我保留未初始化指针的C概念,以这种方式使用?感谢您提出的任何建议.
为了清楚起见,注释:Swift将对CCCryptorCreate()的调用解释如下:
CCCryptorCreate(op: CCOperation, alg: CCAlgorithm, options: CCOptions,
key: CConstVoidPointer, keyLength: UInt, iv: CConstVoidPointer,
cryptorRef: CMutablePointer<Unmanaged<CCCryptor>?>)
Run Code Online (Sandbox Code Playgroud)
对我尝试过的其他一些事情进行了额外的编辑:为了真正荒谬,我尝试了以下内容,但它也没有用(EXC_BAD_ACCESS调用fromOpaque):
var someMem = malloc(UInt(sizeof(CCCryptor)))
var crashTime = Unmanaged<CCCryptor>.fromOpaque(someMem)
Run Code Online (Sandbox Code Playgroud)
此外,每个地方都提到CCCryptor或CCCryptorRef,我已经尝试过任何一个 - 在CommonCrypto/CommonCryptor.h中,CCCryptorRef是这样定义的:
typedef struct _CCCryptor *CCCryptorRef
Run Code Online (Sandbox Code Playgroud)
因此,虽然现有的Objective-C代码示例使用CCCryptorRef,但我一直在尝试.
尝试这个:
var myCryptor: Unmanaged<CCCryptor>?
CCCryptorCreate( .... , &myCryptor )
Run Code Online (Sandbox Code Playgroud)
来自将 Swift 与 Cocoa 和 Objective-C 结合使用
如果你声明了一个像这样的函数:
Run Code Online (Sandbox Code Playgroud)func takesAMutablePointer(x: CMutablePointer<Float>) { /*...*/ }您可以通过以下任意方式调用它:
Run Code Online (Sandbox Code Playgroud)var x: Float = 0.0 var p: CMutablePointer<Float> = nil var a: Float[] = [1.0, 2.0, 3.0] takesAMutablePointer(nil) takesAMutablePointer(p) takesAMutablePointer(&x) takesAMutablePointer(&a)
您还应该检查一下并将引用转换Unmanaged为可管理的内容。
| 归档时间: |
|
| 查看次数: |
3878 次 |
| 最近记录: |