Вопрос

The manpage for libffi features an example that, essentially, requires a pointer to the function (in the examples case, puts).

However, what do I do if I only know the name of the function, but don't actually have a pointer (which would usually happen if ffi is used in, say, dynamic programming languages)?

Say, I want to do something like this (pseudocode):

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)

In short, i want to have libffi dynamically look up the function (if that's supported by ffi in the first place) similar to dlfcn/LoadLibrary, and then call it with the supplied FFI CIF types.

Is such a thing possible with libffi? What would a simple example look like?

Это было полезно?

Решение

There are two possibilities - one requiring premeditation on the part of the programmer.

Depending on the o/s, there are facilities associated with shared libraries for finding symbols from the program or its shared libraries.

On many Unix systems and Linux specifically, the facilities are declared in <dlfcn.h> and are dlopen() and dlsym() (and dlclose(), etc). Given an appropriate handle for the shared library, then you can use:

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

You have to consider the casting - usually brutal - to avoid compilation warnings.

The alternative, premeditated technique is to build a table of function names and function pointers, in which you can search for the name and use the corresponding pointer:

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) } ;

Note that this technique allows for synonyms in a way that the dlsym() mechanism does not. However, the premeditation is often a major stumbling block. It is a technique that harks back to the 80s and early 90s when shared libraries were not universally available. Once again, the need for casts can make the code somewhat more complex.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top