pythoncpython-cfficffi

How to implement a C interface in Python and pass objects using CFFI


I would like to know how to use an existing C interface (a header file) and implement such an interface in Python by using the CFFI library.

For example, I have the following header file, interface.h:

void* foo(void* value);

And I want to implement it in Python. I thought the following program would do the work work, but it doesn't. It creates the function foo, but it doesn't guarantee that the implementation follows the structure defined in the header file.

import cffi

ffibuilder = cffi.FFI()

with open('interface.h') as f:
    data = ''.join([line for line in f if not line.startswith('#')])
    ffibuilder.embedding_api(data)

ffibuilder.set_source("_lib", r'''
    #include "interface.h"
''')

ffibuilder.embedding_init_code("""
    from _lib import ffi

     #include "interface.h"

    @ffi.def_extern()
    def foo(param):
        return __import__(param)

""")

ffibuilder.compile(verbose=True)

How to pass Python objects using CFFI?

In the above example, as a result of calling foo that returns a Python object. Then on the client-side, I have the following:

ffi = FFI()
# Load my lib file
lib = C.CDLL(dll)

h = lib.foo("math")

When I look up the value of h, it shows a number of type integer. However, I was expecting to receive an object. According to the interface, foo must return a pointervoid*. How can I read that object from it? Am I doing something wrong?


Solution

  • To answer your last question: you are using ctypes, not cffi, in this example. These are different project. It should be apparent because the ffi object is from cffi, but is unused in the following lines. Instead of lib = C.CDLL() with I guess C being an alias to ctypes, you should call lib = ffi.dlopen("...")!