использование objc_msgSend для вызова функции Objective C с именованными аргументами

Попробуйте передать значение a и сравните с помощью метода equals следующим образом:

public static void main(String str[]) {

    boolean b = str[0].equals("a");

    System.out.println(b);

}

Следуйте этой ссылке, чтобы узнать больше о Аргумент командной строки в Java

23
задан Markus Pilman 4 April 2010 в 07:08
поделиться

3 ответа

objc_msgSend(object, sel_getUid("foo:bar:err:"), var, var2, errVar);

Если одной из переменных является float, вам нужно использовать метод @Ken или чит путем реинтерпретации:

objc_msgSend(..., *(int*)&var, ...)

Кроме того, если селектор возвращает число с плавающей запятой, вам может понадобиться использовать objc_msgSend_fpret, а если он возвращает структуру, вы должны использовать objc_msgSend_stret. Если это вызов суперкласса, вам нужно использовать objc_msgSendSuper2.

20
ответ дан Community 4 April 2010 в 07:08
поделиться

objc_msgSend (obj, @selector (foo: bar: err :), var, var2 и & errVar);

3
ответ дан Azeem.Butt 4 April 2010 в 07:08
поделиться

Принятый ответ близок, но он не будет работать должным образом для некоторых типов. Например, если метод объявлен как второй аргумент с плавающей точкой, это не сработает.

Чтобы правильно использовать 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.

45
ответ дан 29 November 2019 в 00:58
поделиться