This talk will present DragonFFI, a Clang/LLVM-based library that allows
calling C functions and using C structures from any languages. It will show
how Clang and LLVM are used to make this happen, and the pros/cons against
similar libraries (like (c)ffi).
In 2014, Jordan Rose and John McCall from Apple presented a talk about using
Clang to call C functions from foreign languages. They showed issues they had
doing it, especially about dealing with various ABI.
DragonFFI provides a way to easily call C functions and manipulate C structures
from any language. Its purpose is to parse C libraries headers without any
modifications and transparently use them in a foreign language, like Python or
Ruby. In order to deal with ABI issues previously demonstrated, it uses Clang
to generate scalar-only wrappers of C functions. It also uses generated debug
metadata to have introspection on structures.
Here is an example of the Python API:
$ python
>>> import pydffi
>>> lib = pydffi.FFI()
>>> lib.cdef("#include <stdio.h>", ["puts"])
>>> lib.puts("Hello world!")
Hello world!
>>> lib.compile("int foo(int a) { puts("hi!"); return a+1; }")
>>> lib.foo(4)
hi!
5
>>> lib.cdef("struct A { int a; short b; }")
>>> C = lib.A(a=4,b=5)
>>> print(C.a,C.b)
4,5
>>> lib.compile('void dump(struct A* obj) { printf("From C: %d %d\n", obj->a, obj->b"); }')
>>> lib.dump(C)
From C: 4, 5
A high-level API provides the easy loading of a C library, that uses the
previous API under the hood:
>>> lib = pydffi.LoadLibrary("/lib/libc.so.6",
headers=["stdio.h","stdlib.h"],
defines=[], include_paths=[])
>>> lib.puts("Hello FFI!")
Hello FFI!
This talk will present the tool, how Clang and LLVM are used to provide these
functionalities, and the pros and cons against what other similar libraries
like (c)ffi [0] [1] are doing. It also aims at gathering feedbacks and user
needs that wouldn't be covered.
Code is available on github.
[0] https://sourceware.org/libffi/
[1] https://cffi.readthedocs.io/en/latest/