Call a c-function using keyword arguments

36 views
Skip to first unread message

Hendrik Dorn

unread,
May 17, 2021, 11:17:08 AM5/17/21
to python-cffi
Hello, 

is there a native cffi way of binding function arguments to keywords? In pybind11 this was pybind::arg("my_function_argument"). I would like to avoid python-wrapping my cffi-wrapped c-function. 

Best regards
-Hendrik

P.S.: See also this question on SO

Armin Rigo

unread,
May 18, 2021, 1:49:28 AM5/18/21
to pytho...@googlegroups.com
Hi Hendrik,

On Mon, 17 May 2021 at 17:17, Hendrik Dorn <dorn.h...@gmail.com> wrote:
> is there a native cffi way of binding function arguments to keywords? In pybind11 this was pybind::arg("my_function_argument"). I would like to avoid python-wrapping my cffi-wrapped c-function.

No, there is no other way. I might be willing to accept a patch to
cffi, though. It would need to be clear when it works and when it
doesn't. In C, the function argument names are ignored and don't need
to be written in headers, so this is valid syntax: ``int foo(int x,
long);``. You can't really call such a function from Python using the
name ``x`` because the second argument is missing a name. But you
could call ``int foo(long, int x);`` as ``foo(42, x=5)`` is OK.

And also, would it apply only to functions declared directly in the
cdef, or also to function pointer types? The latter requires touching
the ``ctype`` of function pointers and might break things, like giving
an error when trying to convert a ``int (*foo_t)(int);`` to a ``int
(*bar_t)(int mystuff);``, so I guess it shouldn't be done. But then,
keyword arguments can only be supported in the API mode (with
set_source()), because in ABI mode (with dlopen()) all exposed C
functions are just regular function pointers.


A bientôt,

Armin

Hendrik Dorn

unread,
May 18, 2021, 4:04:42 AM5/18/21
to python-cffi
Bonjour Armin, 

Would these problems also occur, if the keyword arguments 
were explicitly declared, not only with name but also with type?
Imagineable is the syntax 

ffi.set_key("my_func_name", keywords=[(''first_type', first_keyword'), ('second_type', 'second_keyword]) 

where the function has to be declared in ffi.cdef(). But since I do not really 
have an overview of possible pitfalls, I can't determine, whether this 
is realistic. In pybind at least it is. Sadly, as much as this could be a nice 
little project, it is out of reach for my capabilities at the moment. 

Thank you for your nice and quick answer. It was very helpful. 
Congratulatins on cffi, it really handles python-c wrapping as 
one wants it to be handled. 

Cordialement
– Hendrik

Armin Rigo

unread,
May 18, 2021, 4:22:42 AM5/18/21
to pytho...@googlegroups.com
Hi again,

On Tue, 18 May 2021 at 10:04, Hendrik Dorn <dorn.h...@gmail.com> wrote:
> Would these problems also occur, if the keyword arguments
> were explicitly declared, not only with name but also with type?
> Imagineable is the syntax
>
> ffi.set_key("my_func_name", keywords=[(''first_type', first_keyword'), ('second_type', 'second_keyword])

No, this doesn't change anything. The problem is not parsing the C
code (pycparser is great for that), the problem is what to do with the
names in the cases I described.

If you are OK with a line like the above, you can already implement
something similar yourself, e.g. (untested):

def named_arguments(fn, *argnames):
names = ', '.join(argnames)
wrapper = eval("lambda %s: _fn(%s)" % (names, names), {'_fn': fn})
wrapper.__name__ = fn.__name__
return wrapper

my_func_name = named_arguments(lib.my_func_name, 'foo', 'bar')
my_other_func = named_arguments(lib.my_other_func, 'x', 'y', 'z')


A bientôt,

Armin.

Hendrik Dorn

unread,
May 18, 2021, 5:53:30 AM5/18/21
to python-cffi
Hello Armin, 

thank you, I will think about it. 
Here is the answer on SO, should it be of any intererst at all. 

Thank you for your help and take care
– Hendrik

Reply all
Reply to author
Forward
0 new messages