I am writing an objc bridge and I found a very efficient way to call objc methods using objc_msgSend.
Basically the code was able to produce a macro that pass to objc_msgSend the right number of parameters from a NSArray (metamacros.h required).
#import "metamacros.h"
#define CFIEXTRACTARGS(COUNT, ARR) \
, ARR[COUNT] \
#define objc_call(RECIEVER, SELECTOR, COUNT, ARR) \
objc_msgSend(RECIEVER, SELECTOR \
metamacro_for_cxt(COUNT, CFIEXTRACTARGS,, ARR) \
) \
Everything works as expected and pretty well but unfortunately I just discovered the due to Apple changes in the most recent runtime, objc_msgSend cannot be directly called without an explicit cast to the right function pointer.
From: https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaTouch64BitGuide/ConvertingYourAppto64-Bit/ConvertingYourAppto64-Bit.html : "Although the prototype for the message functions has a variadic form, the method function that is called by the Objective-C runtime does not share the same prototype. The Objective-C runtime directly dispatches to the function that implements the method, so the calling conventions are mismatched, as described previously. Therefore you must cast the objc_msgSend function to a prototype that matches the method function being called."
Example:
- (int) doSomething:(int) x { ... }
- (void) doSomethingElse {
int (*action)(id, SEL, int) = (int (*)(id, SEL, int)) objc_msgSend;
action(self, @selector(doSomething:), 0);
}
Obviously I cannot cannot create a cast for every functions combination so I wondering what could be a valid alternative. An NSInvocation would be really too slow.