| import cffi | |
| ffi = cffi.FFI() | |
| ffi.cdef(""" | |
| int my_algo(int); | |
| typedef ... va_list; | |
| extern "Python" int f(int, va_list *); | |
| int fetch_int(va_list *); | |
| double fetch_double(va_list *); | |
| void *fetch_ptr(va_list *); | |
| """) | |
| ffi.set_source("_extern_python_cffi", """ | |
| #include <stdarg.h> | |
| static int f(int, va_list *); | |
| static int f1(int n, ...) | |
| { | |
| va_list ap; | |
| va_start(ap, n); | |
| int res = f(n, &ap); | |
| va_end(ap); | |
| return res; | |
| } | |
| static int fetch_int(va_list *va) { return va_arg((*va), int); } | |
| static double fetch_double(va_list *va) { return va_arg((*va), double); } | |
| static void * fetch_ptr(va_list *va) { return va_arg((*va), void *); } | |
| static int my_algo(int n) { | |
| return f1(3, n, n+1, n+2) + f1(1, &n) + f1(2, 12.3, 45.6); | |
| } | |
| """) | |
| ffi.compile() | |
| from _extern_python_cffi import ffi, lib | |
| @ffi.def_extern() | |
| def f(n, va): | |
| if n == 3: | |
| x = lib.fetch_int(va) | |
| y = lib.fetch_int(va) | |
| z = lib.fetch_int(va) | |
| print (x, y, z) | |
| elif n == 1: | |
| ptr = lib.fetch_ptr(va) | |
| print 'ptr to:', ffi.cast("int *", ptr)[0] | |
| elif n == 2: | |
| x = lib.fetch_double(va) | |
| y = lib.fetch_double(va) | |
| print (x, y) | |
| else: | |
| raise AssertionError(n) | |
| return 14 | |
| print lib.my_algo(10) |