Как вызвать функцию c из имени, которое хранится в указателе char *? - PullRequest
6 голосов
/ 28 июня 2011

Я хотел бы динамически вызывать функцию по ее имени, например, предположим, есть следующая функция и строка:

void do_fork()
{
   printf ("Fork called.\n");

}

char *pFunc = "do_fork";

Теперь мне нужно вызвать do_fork() просто *pFunc.Так возможно ли это?

Приветствуется любой код C / C ++, большое спасибо!

Ответы [ 5 ]

14 голосов
/ 28 июня 2011

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

В C ++ более или менее канонический способ сделать это - использовать карту строк для работы указателей.Примерно так:

typedef void (*func_t)();
typedef std::map<std::string,func_t> func_map_t;

// fill the map
func_map_t func_map;
func_map["do_fork"] = &do_fork;
func_map["frgl"] = &frgl;

// search a function in the map
func_map_t::const_iterator it = func_map.find("do_fork");
if( it == func_map.end() ) throw "You need error handling here!"
(*it->second)();

Конечно, это ограничено функциями с точно такой же сигнатурой.Однако это ограничение может быть несколько снято (чтобы охватить разумно совместимые подписи), используя std::function и std::bind вместо простого указателя функции.

4 голосов
/ 28 июня 2011

Не совсем уверен, что это то, что вы ищете, но вы можете легко использовать dlopen и dlsym.

void *dlsym(void *restrict handle, const char *restrict name);

Функция dlsym () должна получить адрессимвол, определенный в объекте, доступ к которому осуществляется с помощью вызова dlopen ().Аргумент handle - это значение, возвращаемое из вызова dlopen () (и которое с тех пор не было освобождено посредством вызова dlclose ()), а name - это имя символа в виде символьной строки.

Тем не менее, в Си это обычно не доходит, так что вам, скорее всего, это не нужно.

1 голос
/ 28 июня 2011

Это действительно возможно, но это не совсем легко.

Что вам нужно сделать, это скомпилировать ваш двоичный файл для динамического связывания; и затем получить функцию с помощью dlsym согласно ответу @ cnicutar.

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

Функция dlsym-in в активном исполняемом файле OTOH становится волосатой.

0 голосов
/ 28 июня 2011

Если вы знаете все функции, которые вам нужно вызвать, и они находятся в одной программе, вы можете использовать это:

void do_fork()
{
    printf ("Fork called.\n");
}

void callFunc(char *funcName)
{
    if (strcmp(funcName, "do_fork") == 0) do_fork();
}

int main()
{
    char *pFunc = "do_fork";
    callFunc(pFunc);
    return 0;
}
0 голосов
/ 28 июня 2011

Если это должно быть сделано с использованием имени функции, и вы не хотите идти по пути cnicutar, вы можете использовать этот метод:

Скомпилируйте каждую функцию в свой собственный * .exe файлИспользуйте систему (PATH_TO_FUNCTION_EXECUTABLE / FUNCTION_NAME) для вызова исполняемого файла.

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