【发布时间】:2014-06-06 20:29:51
【问题描述】:
我正在尝试在 Apple Swift 中实现一些 AES256 加密例程,以玩弄 ObjC、C 和 Swift 代码和数据类型之间的互操作性,但遇到了一些问题,希望有人能提供一些建议关于我忽略的事情。
正如大多数人所熟悉的,常见的 C 样式模式是声明一个未初始化的指针,然后将其传递给一个函数,其中函数调用 malloc() 并将指针指向它;函数调用完成后,指针指向新创建的对象。 Common Crypto 库在某些地方使用它;最值得注意的是,当创建一个新的 CCCryptor 对象时(实际上是一个幕后结构,看起来,类型定义为 CCCryptorRef 以获得不透明的引用) - 调用 CCCryptorCreate() 的最后一个参数就是这样一个指针,并且应该在函数调用结束,包含指向 CCCryptorRef 的指针。
Swift 对此提出了质疑 - 变量不能未初始化,它们要么总是有值要么为零(/可选),因此我在这里遇到了一些问题。以下内容不起作用,因为 CCCryptorCreate (正确地)表现得好像我只是将 nil 作为最后一个参数传递,我就是这样:
var myCryptorRef: CMutablePointer<Unmanaged<CCCryptorRef>?> = nil
CCCryptorCreate(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES128),
CCOptions(kCCOptionECBMode), seedData.bytes(), UInt(kCCKeySizeAES256),
nil, myCryptorRef)
但是你也不能像这样声明它为可选的:
var myCryptorRef: CMutablePointer<Unmanaged<CCCryptorRef>?>?
或者作为非指针类型:
var myCryptoRef: Unmanaged<CCCryptorRef>?
CCCryptorCreate(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES128),
CCOptions(kCCOptionECBMode), seedData.bytes(), UInt(kCCKeySizeAES256),
nil, &myCryptorRef)
由于 CCCryptorCreate 期望的是指向 CCCryptorRef 的未初始化指针或已经 malloc() 的 CCCryptorRef,因此尝试将尚未初始化的对象的地址传递给它并不像您预期的那样顺利.
所以,归结为:在调用 CCCryptorCreate 之前,任何人都可以想出一种方法来初始化 CCCryptor 结构(通过命名结构内的所有变量来命名结构 init 的 Swift 标准方法似乎不起作用) ,或者一些替代结构,可以让我保留未初始化指针的 C 概念以便以这种方式使用?感谢您提出的任何建议。
为了清楚起见,来自 cmets:Swift 将对 CCCryptorCreate() 的调用解释如下:
CCCryptorCreate(op: CCOperation, alg: CCAlgorithm, options: CCOptions,
key: CConstVoidPointer, keyLength: UInt, iv: CConstVoidPointer,
cryptorRef: CMutablePointer<Unmanaged<CCCryptor>?>)
对我尝试过的其他一些事情进行了额外的编辑:为了真正荒谬,我尝试了以下方法,但它也没有奏效(调用 fromOpaque 时的 EXC_BAD_ACCESS):
var someMem = malloc(UInt(sizeof(CCCryptor)))
var crashTime = Unmanaged<CCCryptor>.fromOpaque(someMem)
此外,CCCryptor 或 CCCryptorRef 提到的每个地方,我都尝试过其中一个 - 在 CommonCrypto/CommonCryptor.h 中,CCCryptorRef 是这样定义的:
typedef struct _CCCryptor *CCCryptorRef
因此,虽然现有的 Objective-C 代码示例使用 CCCryptorRef,但我也一直在尝试。
【问题讨论】:
-
如果您为
CCCryptorCreate添加了什么 Swift 类型(又名函数签名)会有所帮助,我不熟悉该 API。特别是它最后一个参数的类型是什么?
标签: swift