cffi: interfejs funkcji zewnętrznych C
Proszę używać cffi do bardziej pythonicznej integracji z C, z wbudowanymi deklaracjami C.
cffi: interfejs funkcji zewnętrznych C to bezpłatna lekcja Python Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Python Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Python Academy zawiera 4 lekcji w sumie.
Czym jest cffi?
cffi (C Foreign Function Interface) umożliwia wywoływanie kodu C z poziomu Pythona za pomocą deklaracji C zamiast klas ctypes. Jest bardziej zgodne z idiomami Pythona i często bezpieczniejsze.
# pip install cffi
from cffi import FFI
ffi = FFI()
ffi.cdef("double sqrt(double x);")
libm = ffi.dlopen(None) # current process
print(libm.sqrt(2.0)) # 1.4142...Tryb ABI a tryb API
ffi.dlopen() to tryb ABI — wywołuje istniejącą bibliotekę współdzieloną w czasie działania. Tryb API kompiluje wrapper C, dzięki czemu jest szybszy i bardziej niezawodny.
from cffi import FFI
ffi = FFI()
# ABI mode (no compile step):
ffi.cdef("int abs(int x);")
libc = ffi.dlopen("libc.so.6") # Linux
print(libc.abs(-42)) # 42Deklaracje cdef
Proszę użyć ffi.cdef() do zadeklarowania sygnatur funkcji C, struktur i typedefów, które mają być używane z poziomu Pythona.
from cffi import FFI
ffi = FFI()
ffi.cdef("""
typedef struct {
double x;
double y;
} Point;
double distance(Point a, Point b);
""")
# lib = ffi.dlopen("mylib.so")Tworzenie struktur C
Proszę użyć ffi.new(), aby zaalokować strukturę C i ustawić jej pola z poziomu Pythona.
from cffi import FFI
ffi = FFI()
ffi.cdef("typedef struct { int x; int y; } Vec2;")
lib = ffi.dlopen(None)
v = ffi.new("Vec2 *")
v.x = 3
v.y = 4
print(v.x, v.y) # 3 4Ciągi znaków i bufory
Proszę użyć ffi.new("char[]", n) dla modyfikowalnych buforów oraz ffi.string(ptr), aby przekonwertować wskaźnik do ciągu znaków C na bajty Pythona.
from cffi import FFI
ffi = FFI()
buf = ffi.new("char[]", b"hello world")
print(ffi.string(buf)) # b"hello world"
# Mutable buffer for output:
out = ffi.new("char[128]")
# c_func(out, 128) # fill the buffer
# result = ffi.string(out).decode()Tryb API z verify
Tryb API kompiluje niewielki moduł wrappera C, zapewniając lepsze bezpieczeństwo typów i wydajność. Proszę użyć ffi.set_source() i przeprowadzić kompilację offline.
from cffi import FFI
ffi = FFI()
ffi.cdef("int add(int a, int b);")
ffi.set_source("_mylib",
"""
int add(int a, int b) { return a + b; }
"""
)
# Build: python build_mylib.py
# from _mylib import ffi, lib
# print(lib.add(3, 4)) # 7Callbacki z C do Pythona
Proszę użyć ffi.callback(), aby opakować funkcję Pythona jako wskaźnik do funkcji C, który można przekazać do biblioteki C.
from cffi import FFI
ffi = FFI()
ffi.cdef("typedef int (*compare_fn)(int, int);")
@ffi.callback("int(int, int)")
def compare(a, b):
return a - b
# pass compare to a C sort functionZarządzanie pamięcią
Obiekty zaalokowane za pomocą ffi.new() należą do Pythona i są automatycznie zwalniane. Proszę użyć ffi.gc(ptr, destructor), aby dołączyć własny destruktor.
from cffi import FFI
ffi = FFI()
# ptr freed when Python GC collects it:
buf = ffi.new("int[10]")
buf[0] = 42
print(buf[0]) # 42
# Custom destructor:
# ptr = ffi.gc(lib.alloc(), lib.free)cffi a ctypes
cffi używa ciągów deklaracji C, które są bardziej naturalne dla programistów C, natomiast ctypes korzysta z klas Pythona. Tryb API cffi jest szybszy, a ctypes nie wymaga kompilacji.
# ctypes approach:
import ctypes
libc = ctypes.CDLL("libc.so.6")
libc.abs.restype = ctypes.c_int
libc.abs.argtypes = [ctypes.c_int]
print(libc.abs(-5)) # 5
# cffi approach:
from cffi import FFI; ffi = FFI()
ffi.cdef("int abs(int);")
lib = ffi.dlopen(None)
print(lib.abs(-5)) # 5Używanie cffi z NumPy
Dane tablicy NumPy można przekazywać bezpośrednio do C za pośrednictwem cffi, używając ffi.cast() i wskaźnika ctypes.data tablicy.
import numpy as np
from cffi import FFI
ffi = FFI()
arr = np.array([1.0, 2.0, 3.0])
ptr = ffi.cast("double *", arr.ctypes.data)
# Now ptr can be passed to a C function expecting double*Obsługa błędów w cffi
Funkcje C zazwyczaj sygnalizują błędy za pomocą wartości zwracanych. Należy sprawdzać wartości zwracane i używać ffi.errno dla kodów błędów POSIX.
import errno as errno_mod
from cffi import FFI
ffi = FFI()
ffi.cdef("int open(const char *path, int flags);")
lib = ffi.dlopen(None)
fd = lib.open(b"/nonexistent", 0)
if fd == -1:
err = ffi.errno
raise OSError(err, "open failed")Szybkie sprawdzenie
Jakiej metody używa cffi do deklarowania sygnatur funkcji C, które mają być wywoływane?
Podsumowanie
cffi używa ffi.cdef() do deklarowania sygnatur C oraz ffi.dlopen() do wywoływania bibliotek w trybie ABI. Tryb API kompiluje wrapper, zapewniając lepszą wydajność. Proszę używać ffi.new() do zarządzania pamięcią C oraz ffi.callback() do callbacków z Pythona do C.
Często zadawane pytania
Czy lekcja „cffi: interfejs funkcji zewnętrznych C” jest bezpłatna?
Tak — pełny tekst „cffi: interfejs funkcji zewnętrznych C” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Python Academy, przejdź na CoddyKit PRO. Kurs Python Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „cffi: interfejs funkcji zewnętrznych C”?
Proszę używać cffi do bardziej pythonicznej integracji z C, z wbudowanymi deklaracjami C. Ćwiczysz Python Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Python Academy?
Nie wymagamy żadnego doświadczenia. Python Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „cffi: interfejs funkcji zewnętrznych C”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Python Academy?
Tak. Każda lekcja Python Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Po co rozszerzenia C? Zastosowania i kompromisy
- ctypes: wywoływanie bibliotek C z Pythona
- cffi: interfejs funkcji zewnętrznych C
- Pisanie modułu rozszerzeń C dla Pythona