草庐IT

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

coder 2023-09-06 原文

我正在尝试在 Apple Swift 中实现一些 AES256 加密例程,以玩弄 ObjC、C 和 Swift 代码和数据类型之间的互操作性,但遇到了一些问题,希望有人能提供一些建议在我忽略的事情上。

正如大多数人所熟悉的,常见的 C 风格模式是声明一个未初始化的指针,然后将其传递给一个函数,其中函数调用 malloc() 一个对象并将指针指向它;函数调用完成后,指针指向新创建的对象。 Common Crypto 库在某些地方使用它;最值得注意的是在创建一个新的 CCCryptor 对象时(实际上是幕后的结构,它看起来像,typedef'ed 到 CCCryptorRef 以获得不透明的引用) - 调用 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)

但是你也不能像这样将它声明为可选的:

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 结构(通过命名结构中的所有变量来命名结构初始化的 Swift 标准方法似乎不起作用) ,或者一些替代结构,可以让我保留未初始化指针的 C 概念,以便以这种方式使用?感谢您提出任何建议。

为了清晰起见,添加评论: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,但我一直在尝试。

最佳答案

试试这个:

var myCryptor: Unmanaged<CCCryptor>?

CCCryptorCreate( .... , &myCryptor )

来自 Using Swift with Cocoa and Objective-C

If you have declared a function like this one:

func takesAMutablePointer(x: CMutablePointer<Float>) { /*...*/ }

You can call it in any of the following ways:

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)

您还应该查看 this并将 Unmanaged 引用转换为托管的内容。

关于swift - 在 Apple Swift 中传递 C 风格的未初始化指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24090148/

有关swift - 在 Apple Swift 中传递 C 风格的未初始化指针?的更多相关文章

  1. ruby-on-rails - 未初始化的常量 Psych::Syck (NameError) - 2

    在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到ruby​​gems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决

  2. ruby-on-rails - 未在 Ruby 中初始化的对象 - 2

    我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调

  3. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

  4. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

  5. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

  6. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

  7. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

  8. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  9. ruby - 为什么当我调用类的实例方法时,初始化不显示为方法? - 2

    我正在写一篇关于在Ruby中几乎一切都是对象的博客文章,我试图通过以下示例来展示这一点:classCoolBeansattr_accessor:beansdefinitialize@bean=[]enddefcount_beans@beans.countendend所以从类中我们可以看出它有4个方法(当然,除非我错了):它可以在创建新实例时初始化一个默认的空bean数组它可以计算它有多少个bean它可以读取它有多少个bean(通过attr_accessor)它可以向空数组写入(或添加)更多bean(也通过attr_accessor)但是,当我询问类本身它有哪些实例方法时,我没有看到默认

  10. ruby-on-rails - 为什么在 Rails 5.1.1 中删除了 session 存储初始化程序 - 2

    我去了这个website查看Rails5.0.0和Rails5.1.1之间的区别为什么5.1.1不再包含:config/initializers/session_store.rb?谢谢 最佳答案 这是删除它的提交:Setupdefaultsessionstoreinternally,nolongerthroughanapplicationinitializer总而言之,新应用没有该初始化器,session存储默认设置为cookie存储。即与在该初始值设定项的生成版本中指定的值相同。 关于

随机推荐