вызвать функцию по "строке" - PullRequest
1 голос
/ 17 марта 2011

Интересно, можно ли сделать что-то вроде:

 call("MyFunction");

и заставить его вызывать функцию с именем MyFunction, не вызывая длинного переключателя или оператора if.

там, вероятно, естькакой-то другой способ сделать это, чего я действительно хочу достичь, это реализовать протокол IRC, который получает сообщения, и на основе тех, которые я хочу вызвать функцию apropiate

Я новичок в C и лучшие практикикак дела, так что, пожалуйста, просветите меня!

Ответы [ 5 ]

4 голосов
/ 17 марта 2011

Не из коробки с C. У вас может быть хеш-карта или словарь, в котором строка является ключом и указателем на функцию. Вы ищите в своем словаре строковый ключ, затем вызываете указатель на функцию.

4 голосов
/ 17 марта 2011

Не без определения таблицы сопоставлений строк и функций и (возможно) какого-то соглашения о передаче аргументов или использования dlopen() (что считается очень продвинутой хакерской атакой).

2 голосов
/ 17 марта 2011

Невозможно напрямую вызвать функцию по строке, как вы хотите, в стандартной библиотеке C.Если бы это был C ++, вы могли бы создать std::map из string для указателя на функцию, но не в C. Возможно, вам придется прибегнуть к серии strcmp s, если C ++ не является опцией.

/* These are your handler functions */
void user_fn() { printf("USER fn\n"); }
void pass_fn() { printf("PASS fn\n"); }

/* Stores a C string together with a function pointer */
typedef struct fn_table_entry {
    char *name;
    void (*fn)();
} fn_table_entry_t;

/* These are the functions to call for each command */
fn_table_entry_t fn_table[] = {{"USER", user_fn}, {"PASS", pass_fn}};

/* fn_lookup is a function that returns the pointer to the function for the given name. 
   Returns NULL if the function is not found or if the name is NULL. */
void (*fn_lookup(const char *fn_name))() {
    int i;

    if (!fn_name) {
        return NULL;
    }
    for (i = 0; i < sizeof(fn_table)/sizeof(fn_table[0]); ++i) {
        if (!strcmp(fn_name, fn_table[i].name)) {
            return fn_table[i].fn;
        }
    }
    return NULL;
}

int main() {
    fn_lookup("USER")();
    fn_lookup("PASS")();
}
0 голосов
/ 17 марта 2011

Я не программист на C, и лично я бы занимался IRC на динамическом языке, но вы могли бы сделать следующее:

создайте структуру со строковым полем и указателем на функцию, создайте массив всех ваших функций с их «строкой», отсортированной по строке. При вызове выполните двоичный поиск в массиве по строке и вызовите указатель функции в найденной структуре.

0 голосов
/ 17 марта 2011

Вы создаете таблицу, которая связывает каждую строку с указателем на функцию. Затем вы ищите строку в таблице и вызываете функцию через указатель. Классический текст K & R содержит код, похожий на этот.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...