Вызов функции по имени, введенному пользователем - PullRequest
3 голосов
/ 10 февраля 2011

Можно ли вызвать функцию по имени в Objective C?Например, если я знаю имя функции ("foo"), могу ли я получить указатель на функцию, используя это имя, и вызвать ее?Я наткнулся на похожий вопрос для python здесь , и, кажется, там это возможно.Я хочу взять имя функции в качестве ввода от пользователя и вызвать функцию.Эта функция не должна принимать никаких аргументов.

1 Ответ

7 голосов
/ 10 февраля 2011

Для методов Objective-C вы можете использовать performSelector… или NSInvocation, например

NSString *methodName = @"doSomething";
[someObj performSelector:NSSelectorFromString(methodName)];

Для функций C в динамических библиотеках вы можете использовать dlsym(), например

void *dlhandle = dlopen("libsomething.dylib", RTLD_LOCAL);
void (*function)(void) = dlsym(dlhandle, "doSomething");
if (function) {
    function();
}

Для функций C, которые были статически связаны, а не вообще.Если соответствующий символ не был удален из двоичного файла, вы можете использовать dlsym(), например,

void (*function)(void) = dlsym(RTLD_SELF, "doSomething");
if (function) {
    function();
}

Обновление: ThomasW написал комментарий, указывающий на связанный вопрос, с ответом dreamlax , который, в свою очередь, содержит ссылку на страницу POSIX о dlsym.В этом ответе dreamlax отмечает следующее относительно преобразования значения, возвращаемого dlsym(), в переменную указателя функции:

Стандарт C фактически не определяет поведение для преобразования в указатели функций и из них.Объяснения различаются относительно того, почему;Наиболее распространенным является то, что не все архитектуры реализуют указатели функций как простые указатели на данные.На некоторых архитектурах функции могут находиться в совершенно другом сегменте памяти, который не может быть переадресован с использованием указателя на void.

С учетом этого вызовы, приведенные выше для dlsym() и требуемой функции могут бытьсделал более переносимым следующим образом:

void (*function)(void);
*(void **)(&function) = dlsym(dlhandle, "doSomething");
if (function) {
    (*function)();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...