Python Academy · leksjon

cffi: C Foreign Function Interface

Bruk cffi for mer Pythonisk C-interoperabilitet med innebygde C-deklarasjoner.

Leksjon 3 av 413 trinn

cffi: C Foreign Function Interface er en gratis leksjon i Python Academy på CoddyKit. Dette er leksjon 3 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Python Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Python Academy inneholder totalt 4 leksjoner.

Hva er cffi?

cffi (C Foreign Function Interface) gjør det mulig å kalle C-kode fra Python ved hjelp av C-deklarasjoner i stedet for ctypes-klasser. Det er mer Python-idiomatisk og ofte sikrere.

# 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...

ABI-modus kontra API-modus

ffi.dlopen() er ABI-modus – den kaller et eksisterende delt bibliotek ved kjøring. API-modus kompilerer en C-wrapper og er raskere og mer robust.

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))   # 42

cdef-deklarasjoner

Bruk ffi.cdef() til å deklarere C-funksjonssignaturer, strukturer og typedef-er som De vil bruke fra Python.

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")

Opprette C-strukturer

Bruk ffi.new() til å allokere en C-struktur og angi feltene fra Python.

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 4

Strenger og buffere

Bruk ffi.new("char[]", n) for mutable buffere og ffi.string(ptr) til å konvertere en peker til en C-streng til Python-bytes.

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()

API-modus med verify

API-modus kompilerer en liten C-wrapper-modul for bedre typesikkerhet og ytelse. Bruk ffi.set_source() og bygg uten nettverk.

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))   # 7

Tilbakekall fra C til Python

Bruk ffi.callback() til å pakke inn en Python-funksjon som en C-funksjonspeker som kan sendes til et C-bibliotek.

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 function

Minnehåndtering

Objekter som allokeres med ffi.new(), eies av Python og frigjøres automatisk. Bruk ffi.gc(ptr, destructor) for å knytte til en egendefinert destruktør.

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 kontra ctypes

cffi bruker strenger med C-deklarasjoner, noe som er mer naturlig for C-utviklere, mens ctypes bruker Python-klasser. API-modusen i cffi er raskere; ctypes krever ingen kompilering.

# 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))    # 5

Bruke cffi med NumPy

Send dataene i en NumPy-array direkte til C via cffi ved hjelp av ffi.cast() og arrayets ctypes.data-peker.

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*

Feilhåndtering med cffi

C-funksjoner signaliserer vanligvis feil via returverdier. Kontroller returverdiene, og bruk ffi.errno for POSIX-feilkoder.

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")

Hurtigsjekk

Hvilken metode bruker cffi til å deklarere C-funksjonssignaturene De vil kalle?

Oppsummering

cffi bruker ffi.cdef() til å deklarere C-signaturer og ffi.dlopen() for bibliotekskall i ABI-modus. API-modus kompilerer en wrapper for bedre ytelse. Bruk ffi.new() for C-minne og ffi.callback() for tilbakekall fra Python til C.

Gratis å komme i gang

Lær deg Python med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
76
Leksjoner
320

Ofte stilte spørsmål

Er leksjonen «cffi: C Foreign Function Interface» gratis?

Ja – hele teksten i «cffi: C Foreign Function Interface» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Python Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Python Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «cffi: C Foreign Function Interface»?

Bruk cffi for mer Pythonisk C-interoperabilitet med innebygde C-deklarasjoner. Du øver på Python Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Python Academy?

Ingen tidligere erfaring er nødvendig. Python Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.

Hvor lang tid tar leksjonen «cffi: C Foreign Function Interface»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Python Academy-leksjonen?

Ja. Alle Python Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Hvorfor C-utvidelser? Bruksområder og avveininger
  2. ctypes: Kalle C-biblioteker fra Python
  3. cffi: C Foreign Function Interface
  4. Skrive en Python C-utvidelsesmodul
← Tilbake til Python Academy