Вызывать имя функции, а не указатель функции - PullRequest
0 голосов
/ 15 января 2012

Страница man для libffi содержит пример, который, по сути, требует указателя на функцию (в случае примеров, puts).

Однако что мне делать, если я знаю только имяфункция, но на самом деле нет указателя (что обычно происходит, если ffi используется, скажем, в динамических языках программирования)?

Скажем, я хочу сделать что-то вроде этого (псевдокод):

cif = null
s = "Hello World"
args = []
values = []
args[0] = ffi.type_pointer
values[0] = address_of(s)
if(ffi.prepare(cif, ffi.DEFAULT_ABI, ffi.type_uint, args)):
     ffi.call(cif, "puts", values)

Короче говоря, я хочу, чтобы libffi динамически просматривал функцию (в первую очередь, если она поддерживается ffi), аналогично dlfcn / LoadLibrary, а затем вызывал ее с помощью предоставленных типов FFI CIF.*

Возможна ли такая вещь в libffi?Как будет выглядеть простой пример?

1 Ответ

0 голосов
/ 15 января 2012

Есть две возможности - одна требует от программиста предумышленности.

В зависимости от o / s, существуют средства, связанные с общими библиотеками для поиска символов из программы или ее общих библиотек.

Во многих системах Unix и, в частности, в Linux средства объявлены в <dlfcn.h> и имеют значения dlopen() и dlsym()dlclose() и т. Д.). Имея соответствующий дескриптор для разделяемой библиотеки, вы можете использовать:

int (*ffi_ptr)(const char *) = dlsym(ffi_handle, "ffi_function_name");

Вы должны рассмотреть кастинг - обычно жестокий - чтобы избежать предупреждений компиляции.

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

struct ptr_function
{
    void (*func_ptr)(void);
    const char *func_name;
};

static const struct ptr_function[] =
{
    { func_1, "func_1"       },
    { func_2, "func_2"       },
    { func_2, "func_synonym" },
};

enum { NUM_PTR_FUNCTION = sizeof(ptr_function) / sizeof(*ptr_function) } ;

Обратите внимание, что этот метод позволяет использовать синонимы так, как этого не делает механизм dlsym(). Тем не менее, премедикация часто является основным камнем преткновения. Это метод, который восходит к 80-м и началу 90-х годов, когда общие библиотеки не были доступны повсеместно. Еще раз, необходимость в приведении может сделать код несколько более сложным.

...