Can Foundation tell me whether an Objective-C method requires a special structure return?

孤街醉人 提交于 2019-12-22 03:56:11

问题


Background as I understand it: Objective-C method invocations are basically a C function call with two hidden parameters (the receiver and the selector). The Objective-C runtime contains a function named objc_msgSend() that allows to invoke methods that way. Unfortunately, when a function returns a struct some special treatment may be needed. There are arcane (some might say insane) rules that govern whether the structure is returned like other values or whether it's actually returned by reference in a hidden first argument. For Objective-C there's another function called objc_msgSend_stret() that must be used in these cases.

The question: Given a method, can NSMethodSignature or something else tell me whether I have to use objc_msgSend() or objc_msgSend_stret()? So far we have found out that NSMethodSignature knows this, it prints it in its debug output, but there doesn't seem to be a public API.

In case you want to respond with "why on earth would you want to do that?!", please read the following before you do: https://github.com/erikdoe/ocmock/pull/41


回答1:


Objective-C uses the same underlying ABI for C on a given architecture, because methods are just C functions with implicit self and _cmd arguments.

In other words, if you have a method:

- (SomeStructType)myMeth:(SomeArgType)arg;

then really this is a plain C function:

SomeStructType myMeth(id self, SEL _cmd, SomeArgType arg);

I'm pretty sure you already know that, but I'm merely mentioning it for other readers. In other words, you want to ask libffi or any kind of similar library how SomeStructType would be returned for that architecture.




回答2:


NSMethodSignature has a -methodReturnType that you can inspect to see if the return type is a struct. Is this what you're trying to do?




回答3:


From http://www.sealiesoftware.com/blog/archive/2008/10/30/objc_explain_objc_msgSend_stret.html:

The rules for which struct types return in registers are always arcane, sometimes insane. ppc32 is trivial: structs never return in registers. i386 is straightforward: structs with sizeof exactly equal to 1, 2, 4, or 8 return in registers. x86_64 is more complicated, including rules for returning floating-point struct fields in FPU registers, and ppc64's rules and exceptions will make your head spin. The gory details are documented in the Mac OS X ABI Guide, though as usual if the documentation and the compiler disagree then the documentation is wrong.

If you're calling objc_msgSend directly and need to know whether to use objc_msgSend_stret for a particular struct type, I recommend the empirical approach: write a line of code that calls your method, compile it on each architecture you care about, and look at the assembly code to see which dispatch function the compiler uses.



来源:https://stackoverflow.com/questions/18143636/can-foundation-tell-me-whether-an-objective-c-method-requires-a-special-structur

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!