在Apple Swift中传递C风格的未初始化指针?

Kha*_*bit 5 swift

我试图在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,但我一直在尝试.

Ana*_*ile 3

尝试这个:

var myCryptor: Unmanaged<CCCryptor>?

CCCryptorCreate( .... , &myCryptor )
Run Code Online (Sandbox Code Playgroud)

来自将 Swift 与 Cocoa 和 Objective-C 结合使用

如果你声明了一个像这样的函数:

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)
Run Code Online (Sandbox Code Playgroud)

您还应该检查一下并将引用转换Unmanaged为可管理的内容。