如何实现IMP函数返回在运行时确定的大型结构类型?

时间:2011-03-29 17:55:51

标签: objective-c perl objective-c-runtime

背景:CamelBones使用Objective-C运行时注册Perl类。 为此,每个Perl方法都使用相同的IMP注册 功能;该函数检查其self&查找_cmd个参数 哪种Perl方法可以调用。

对于那些消息来说,这已经好几年了 与objc_msgSend一起发送。但现在我想添加支持 从Perl方法返回浮点和大型结构类型。 浮点并不难;我只会写另一个返回的IMP double,用于处理使用objc_msgSend_fpret发送的消息。

问题是如何处理objc_msgSend_stret。写一个 对于每个可能的结构返回类型,单独的IMP是不切实际的 原因有二:首先,因为即使我这样做只针对结构类型 在编译时已知,这是一个荒谬的函数数量。 第二,因为我们正在谈论一个可以与任意Objective-C& Perl代码,我们在编译框架时知道所有潜在的结构类型。

我希望做的是写一个可以处理任何回报的IMP 通过objc_msgSend_stret发送的类型。我可以把它写成 返回void,并将指针参数传递给返回缓冲区,如 宣布旧objc_msgSend_stret?即使发生了这种情况 现在工作,我可以依靠它继续在未来工作吗?

感谢您的任何建议 - 我一直在为这个问题绞尽脑汁。 : - )

更新

以下是我从Apple的一位运行工程师那里收到的关于他们的objc语言邮件列表的建议:

  

您必须编写要处理的汇编代码   这种情况。

     

你的建议失败了   架构,其中ABI为“功能   使用指针返回void   struct作为第一个参数“不同   来自“函数返回结构”。   (在i386上,弹出结构地址   来自堆栈的呼叫者在一个   案件和被调用者在另一个案件中   case。)这就是原型的原因   objc_msgSend_stret已更改。

     

汇编代码将捕获   struct返回地址,将其走私到   非结构返回C函数调用   没有打扰其余的   参数,然后做正确的   退出时针对ABI的清理(ret $4   在i386上)。或者,组装   代码可以捕获所有的   参数。转发机械   做这样的事情。那段代码   可能在开源CoreFoundation中   如果你想看看哪些技巧   看起来像。

我会把这个问题保持开放,以防有人集体讨论更好的想法,但直接来自Apple自己的“运行时争吵者”,我认为这可能是我可能得到的权威答案。是时候把x86参考手册上的灰尘弄掉了,然后把我的装配工的铁锈搞定了,我猜......

1 个答案:

答案 0 :(得分:5)

Apple工程师似乎是对的:唯一要走的路是汇编代码。以下是一些有用的入门指南:

  • 来自Objective-C运行时代码:The i386x86_64手工制作的messenger assmbly存根,用于各种消息传递方法。
  • An SO answer概述了调度。
  • A in-depth review调度机制以及对汇编代码的逐行分析

希望它有所帮助。