59

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

对于使用objc_msgSend. 但现在我想添加对从 Perl 方法返回浮点和大型结构类型的支持。浮点并不难;我将简单地编写另一个返回 double 的 IMP 来处理以objc_msgSend_fpret.

问题是该怎么办objc_msgSend_stret。为每个可能的结构返回类型单独编写一个IMP是不切实际的,原因有两个:首先,因为即使我只为在编译时已知的结构类型这样做,这也是一个荒谬的函数数量。其次,因为我们讨论的是一个可以链接到任意 Objective-C 和 Perl 代码的框架,所以在编译框架时我们知道所有潜在的结构类型。

我希望做的是编写一个IMP可以处理任何通过objc_msgSend_stret. 我可以将它写为返回void,并将指针参数传递给返回缓冲区,就像objc_msgSend_stret声明旧的一样?即使这碰巧现在有效,我可以依靠它在未来继续工作吗?

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

更新:

这是我从 Apple 的一位运行时工程师那里收到的建议,在他们的 objc 语言邮件列表中:

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

您的建议在某些架构上失败,其中“函数返回 void 并以指向结构的指针作为第一个参数”的 ABI 与“函数返回结构”不同。(在 i386 上,结构地址在一种情况下由调用者从堆栈中弹出,在另一种情况下由被调用者从堆栈中弹出。)这就是 objc_msgSend_stret更改原型的原因。

汇编代码将捕获结构返回地址,将其偷运到非结构返回 C 函数调用中,而不会干扰其余参数,然后在退出时(ret $4 在 i386 上)进行正确的 ABI 特定清理。或者,汇编代码可以捕获所有参数。转发机器会做这样的事情。如果您想了解这些技术是什么样子,那么该代码可能位于开源 CoreFoundation 中。

我会留下这个问题,以防有人集思广益,但这个问题直接来自苹果自己的“运行时牧马人”,我认为这可能是我可能得到的最权威的答案。是时候清理 x86 参考手册的灰尘并敲掉我的汇编器上的锈迹了,我猜...

4

1 回答 1

5

看来苹果工程师是对的:唯一的出路就是汇编代码。以下是一些有用的入门指南:

希望能帮助到你。

于 2011-05-23T07:48:23.720 回答