Принятый ответ близок, но он не будет работать должным образом для определенных типов. Например, если объявлен метод, который принимает float в качестве второго аргумента, это не сработает.
Чтобы правильно использовать objc_msgSend, вы должны привести его к соответствующему типу. Например, если ваш метод объявлен как
- (void)foo:(id)foo bar:(float)bar err:(NSError **)err
тогда вам нужно будет сделать что-то вроде этого:
void (*objc_msgSendTyped)(id self, SEL _cmd, id foo, float bar, NSError**error) = (void*)objc_msgSend;
objc_msgSendTyped(self, @selector(foo:bar:err:), foo, bar, error);
Попробуйте описанный выше случай только с objc_msgSend и выйдите из полученных аргументов. Вы не увидите правильные значения в вызываемой функции. Эта необычная ситуация приведения возникает из-за того, что objc_msgSend не предназначен для вызова как обычная функция C. Он (и должен быть) реализован на ассемблере и просто переходит к целевой функции C после того, как возится с несколькими регистрами. В частности, не является последовательным способом ссылки на любой аргумент после первых двух из objc_msgSend.
Другой случай, когда простой вызов objc_msgSend не сработает, это метод, который возвращает NSRect, скажем, потому что objc_msgSend не используется в этом случае, objc_msgSend_stret - это. В базовой функции C для метода, который возвращает NSRect, первый аргумент фактически является указателем на выходное значение NSRect, а сама функция фактически возвращает void. Вы должны соответствовать этому соглашению при вызове, потому что это то, что будет вызывать вызываемый метод. Кроме того, обстоятельства, в которых используется objc_msgSend_stret, отличаются в разных архитектурах. Существует также objc_msgSend_fpret, который следует использовать для методов, которые возвращают определенные типы с плавающей запятой на определенных архитектурах.
Теперь, так как вы пытаетесь создать скрипт-мост, вы, вероятно, не можете явным образом привести все случаи, когда сталкиваетесь, вам нужно общее решение. В общем, это не совсем тривиально, и, к сожалению, ваш код должен быть специализирован для каждой архитектуры, на которую вы хотите ориентироваться (например, i386, x86_64, ppc). Лучше всего, вероятно, увидеть, как PyObjC делает это. Вы также захотите взглянуть на libffi . Вероятно, неплохо бы немного больше узнать о том, как параметры передаются в C, о чем вы можете прочитать в Mac OS X ABI Guide . Наконец, Грег Паркер, который работает во время выполнения objc, написал кучу очень хороших сообщений о внутренних объектах objc.