Reputation: 21
Using the API mode, calling C sources instead of a compiled library in the python-cffi framework I want to call my c-function in python with keyword arguments. Is there an inbuilt feature in cffi for this? Otherwise I would have to write a python wrapper around my cffi-wrapped c-functions which I don't want to do since it seems like an ugly solution.
(run both files with python, should work out-of-the-box if cffi and gcc are present: "python example_extension_build.py && python test_example.py")
Note: That in this Example code I use the API level, out-of-line mode instead (for clearnes)
# file: example_extension_build.py
from cffi import FFI
ffibuilder = FFI()
# objects shared between c and python
ffibuilder.cdef("""
struct my_s{ int a; char * b; };
int my_f(int, struct my_s);
""")
# definitions of the python-c shared objects
ffibuilder.set_source("_example",r"""
struct my_s{ int a; char * b; };
#include <stdio.h>
int my_f(int arg_1, struct my_s arg_2) // some random example function
{
printf("%s\n", arg_2.b);
return arg_1 + arg_2.a;
}
""", sources=[])
if __name__ == "__main__" :
ffibuilder.compile(verbose=True)
And the python calls
# file: test_example.py
import _example as e
n = 21;
s = e.ffi.new("struct my_s *")
s.a = 21
s.b = e.ffi.new("char[]", b"Hello World!")
# e.lib.my_f(arg_2=s[0], arg_1=n); # <-- Here is what I want
e.lib.my_f(n, s[0]); # the standard way
Upvotes: 1
Views: 626
Reputation: 21
As of today – May 18 2021 – it is not possible to wrap a c function with cffi as to expose keyword arguments to python. This answer was provided by Armin Rigo on the cffi mailing list here (a patch to provide this feature will be accepted by Armin Rigo, if certain conditions are fulfilled). The only possible solution then is to wrap the cffi-wrapped c-function in python code (ugh).
Note: Even uglier will it get, if one wanted to set a default argument value for arg_2
# file: test_wrap.py
import _example as e
def my_f(arg_1, arg_2) :
return e.lib.my_f(arg_1, arg_2)
n = 21
s = e.ffi.new("struct my_s *")
s.a = 21
s.b = e.ffi.new("char[]", b"Hello World!")
sol = my_f(arg_2=s[0], arg_1=n) # <-- Here is what I want
print(sol)
On the command line
$ python test_wrap.py
Hello World!
42
Upvotes: 0