0Pricing
Python Academy · Lección

cffi: interfaz de funciones externas de C

Utilice cffi para una interoperabilidad con C más propia de Python, con declaraciones C insertadas.

cffi: interfaz de funciones externas de C es una lección gratuita de Python Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Python Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Python Academy incluye 4 lecciones en total.

¿Qué es cffi?

cffi (C Foreign Function Interface) permite llamar a código C desde Python mediante declaraciones de C en lugar de clases de ctypes. Es más idiomático en Python y suele ser más seguro.

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

Modo ABI frente a modo API

ffi.dlopen() es el modo ABI: llama a una biblioteca compartida existente en tiempo de ejecución. El modo API compila un wrapper de C y es más rápido y robusto.

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

Declaraciones cdef

Use ffi.cdef() para declarar las signaturas de funciones de C, las estructuras y los typedefs que quiera utilizar desde 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")

Creación de estructuras de C

Use ffi.new() para asignar una estructura de C y establecer sus campos desde 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

Cadenas y búferes

Use ffi.new("char[]", n) para los búferes mutables y ffi.string(ptr) para convertir un puntero a una cadena de C en bytes de Python.

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

Modo API con verify

El modo API compila un pequeño módulo wrapper de C para ofrecer mayor seguridad de tipos y rendimiento. Use ffi.set_source() y compile sin conexión.

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

Callbacks de C a Python

Use ffi.callback() para envolver una función de Python como un puntero a función de C que pueda pasar a una biblioteca de 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 function

Gestión de memoria

Los objetos asignados con ffi.new() pertenecen a Python y se liberan automáticamente. Use ffi.gc(ptr, destructor) para asociar un destructor personalizado.

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 frente a ctypes

cffi utiliza cadenas de declaraciones de C (más naturales para los desarrolladores de C), mientras que ctypes utiliza clases de Python. El modo API de cffi es más rápido; ctypes no requiere compilación.

# 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

Uso de cffi con NumPy

Pase directamente los datos de una matriz de NumPy a C mediante cffi usando ffi.cast() y el puntero ctypes.data de la matriz.

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*

Gestión de errores con cffi

Las funciones de C suelen indicar los errores mediante valores de retorno. Compruebe los valores de retorno y use ffi.errno para los códigos de error 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")

Comprobación rápida

¿Qué método utiliza cffi para declarar las signaturas de las funciones de C que quiere llamar?

Recapitulación

cffi utiliza ffi.cdef() para declarar signaturas de C y ffi.dlopen() para llamar a bibliotecas en modo ABI. El modo API compila un wrapper para mejorar el rendimiento. Use ffi.new() para la memoria de C y ffi.callback() para los callbacks de Python a C.

Preguntas frecuentes

¿La lección «cffi: interfaz de funciones externas de C» es gratis?

Sí — el texto completo de «cffi: interfaz de funciones externas de C» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Python Academy, actualiza a CoddyKit PRO. El curso de Python Academy incluye 4 lecciones en total.

¿Qué aprenderé en «cffi: interfaz de funciones externas de C»?

Utilice cffi para una interoperabilidad con C más propia de Python, con declaraciones C insertadas. Practicas Python Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Python Academy?

No se requiere experiencia previa. Python Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «cffi: interfaz de funciones externas de C»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Python Academy?

Sí. Cada lección de Python Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. ¿Por qué extensiones C? Casos de uso y compensaciones
  2. ctypes: llamada a bibliotecas C desde Python
  3. cffi: interfaz de funciones externas de C
  4. Escritura de un módulo de extensión C para Python
← Volver a Python Academy