Callbacks: pasar funciones de Lua a C
Utilice ffi.cast para crear callbacks C que vuelvan a llamar a código Lua.
Callbacks: pasar funciones de Lua a C es una lección gratuita de Lua Academy en CoddyKit. Esta es la lección 4 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 Lua Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Lua Academy incluye 4 lecciones en total.
¿Qué son las devoluciones de llamada de C?
Algunas API de C requieren que pase un puntero a función que el código de C llamará posteriormente. ffi.cast de FFI permite crear punteros a funciones compatibles con C a partir de funciones de Lua.
Declarar un tipo de devolución de llamada
Primero declare el tipo de puntero a función en cdef.
local ffi = require("ffi")
ffi.cdef[[
typedef void (*callback_t)(int event, void *data);
void register_handler(callback_t cb);
]]Crear una devolución de llamada
Use ffi.cast("callback_t", luaFunc) para envolver una función de Lua como devolución de llamada de C. El resultado es un puntero a función de C que puede pasar al código de C.
local function myHandler(event, data)
print("Event:", event)
end
local cb = ffi.cast("callback_t", myHandler)
lib.register_handler(cb)Duración de una devolución de llamada
Conserve una referencia de Lua al objeto de devolución de llamada (cb). Si el GC lo libera, llamar al puntero a función de C provocará un error. Guárdelo en una variable o tabla de larga duración.
local callbacks = {} -- prevent GC
callbacks[#callbacks+1] = ffi.cast("callback_t", myHandler)
lib.register_handler(callbacks[#callbacks])Ordenar con un comparador de C
Pase un comparador de Lua a qsort de C mediante una devolución de llamada de FFI.
ffi.cdef[[
typedef int (*cmp_t)(const void *a, const void *b);
void qsort(void *base, size_t nmemb, size_t size, cmp_t cmp);
]]
local arr = ffi.new("int[5]", {3,1,4,1,5})
local cmp = ffi.cast("cmp_t", function(a, b)
return ffi.cast("int*", a)[0] - ffi.cast("int*", b)[0]
end)
ffi.C.qsort(arr, 5, ffi.sizeof("int"), cmp)
for i = 0, 4 do io.write(arr[i] .. " ") endDevoluciones de llamada y corrutinas
Las devoluciones de llamada de Lua llamadas desde C no pueden ceder la ejecución (llamar a coroutine.yield). El lado de C no admite el cambio de corrutina de Lua. Diseñe las devoluciones de llamada para que no cedan la ejecución.
Upvalues en devoluciones de llamada
Las devoluciones de llamada de Lua pueden capturar upvalues con normalidad. Esto permite que accedan al contexto (por ejemplo, un objeto o una tabla de estado) sin usar variables globales.
local function makeHandler(ctx)
return ffi.cast("callback_t", function(event, _)
ctx.lastEvent = event -- upvalue access
end)
endControladores de señales
Registre funciones de Lua como controladores de señales de Unix mediante FFI. Tenga cuidado: los controladores de señales tienen restricciones importantes sobre las funciones de C que pueden llamar.
Gestión de memoria de las devoluciones de llamada
Libere las devoluciones de llamada con cb:free() después de anular su registro en el lado de C. Las fugas de objetos de devolución de llamada desperdician memoria.
Alternativa: funciones envoltorio de C
Para integraciones complejas, un adaptador fino en C puede ser más claro que las devoluciones de llamada de FFI. El adaptador vuelve a llamar a Lua mediante la API de C, lo que proporciona control total sobre las corrutinas y la gestión de errores.
Rendimiento
Las devoluciones de llamada de FFI son rápidas, pero no tanto como las llamadas directas de FFI, ya que el puente de C a Lua implica una sobrecarga de configuración. Para devoluciones de llamada de frecuencia muy alta (por ejemplo, de audio), considere implementaciones completamente en C.
Pregunta sobre callbacks
¿Por qué debe conservar una referencia de Lua a un objeto callback de FFI?
Repaso: callbacks de FFI
Utilice ffi.cast("fn_ptr_type", luaFunc) para crear callbacks compatibles con C. Conserve siempre una referencia para evitar que el recolector de basura lo libere. Los callbacks no pueden ceder la ejecución. Utilice upvalues para pasar contexto a los callbacks.
Preguntas frecuentes
¿La lección «Callbacks: pasar funciones de Lua a C» es gratis?
Sí — el texto completo de «Callbacks: pasar funciones de Lua a 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 Lua Academy, actualiza a CoddyKit PRO. El curso de Lua Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Callbacks: pasar funciones de Lua a C»?
Utilice ffi.cast para crear callbacks C que vuelvan a llamar a código Lua. Practicas Lua 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 Lua Academy?
No se requiere experiencia previa. Lua 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 4 de 4.
¿Cuánto tiempo toma la lección «Callbacks: pasar funciones de Lua a 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 Lua Academy?
Sí. Cada lección de Lua 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
- Conceptos básicos de FFI: ffi.cdef y ffi.load
- Llamada a funciones C mediante FFI
- Punteros, structs y arrays en FFI
- Callbacks: pasar funciones de Lua a C