Callback: passaggio di funzioni Lua a C
Utilizzi ffi.cast per creare callback C che richiamano codice Lua.
Callback: passaggio di funzioni Lua a C è una lezione Lua Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Lua Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Lua Academy include 4 lezioni in totale.
Che cosa sono i callback C?
Alcune API C richiedono di passare un puntatore a funzione che il codice C chiamerà successivamente. ffi.cast dell'FFI consente di creare puntatori a funzione compatibili con C a partire da funzioni Lua.
Dichiarare un tipo callback
Per prima cosa, dichiari il tipo puntatore a funzione in cdef.
local ffi = require("ffi")
ffi.cdef[[
typedef void (*callback_t)(int event, void *data);
void register_handler(callback_t cb);
]]Creare un callback
Utilizzi ffi.cast("callback_t", luaFunc) per racchiudere una funzione Lua in un callback C. Il risultato è un puntatore a funzione C che può essere passato al codice C.
local function myHandler(event, data)
print("Event:", event)
end
local cb = ffi.cast("callback_t", myHandler)
lib.register_handler(cb)Durata del callback
Mantenga un riferimento Lua all'oggetto callback (cb). Se viene raccolto dal GC, la chiamata al puntatore a funzione C causerà un crash. Lo memorizzi in una variabile o tabella di lunga durata.
local callbacks = {} -- prevent GC
callbacks[#callbacks+1] = ffi.cast("callback_t", myHandler)
lib.register_handler(callbacks[#callbacks])Ordinare con un comparatore C
Passi un comparatore Lua alla funzione C qsort tramite un callback 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] .. " ") endCallback e coroutine
I callback Lua chiamati da C non possono sospendersi (chiamando coroutine.yield). Il lato C non supporta il cambio di coroutine di Lua. Progetti i callback in modo che non si sospendano.
Upvalue nei callback
I callback Lua possono catturare normalmente gli upvalue. Ciò consente ai callback di accedere al contesto, ad esempio a un oggetto o a una tabella di stato, senza utilizzare variabili globali.
local function makeHandler(ctx)
return ffi.cast("callback_t", function(event, _)
ctx.lastEvent = event -- upvalue access
end)
endGestori dei segnali
Registri funzioni Lua come gestori dei segnali Unix tramite FFI. Faccia attenzione: i gestori dei segnali sono soggetti a forti restrizioni sulle funzioni C che possono chiamare.
Gestione della memoria dei callback
Rilasci i callback con cb:free() dopo averli deregistrati dal lato C. Lasciare oggetti callback non rilasciati spreca memoria.
Alternativa: funzioni wrapper C
Per integrazioni complesse, uno shim C sottile può essere più pulito dei callback FFI. Lo shim richiama Lua tramite la C API, offrendo il pieno controllo sulle coroutine e sulla gestione degli errori.
Prestazioni
I callback FFI sono veloci, ma non quanto le chiamate FFI dirette, poiché il ponte da C a Lua comporta un sovraccarico di configurazione. Per callback ad altissima frequenza, ad esempio nell'audio, valuti implementazioni interamente in C.
Domanda sui callback
Perché è necessario conservare un riferimento Lua a un oggetto callback FFI?
Riepilogo: callback FFI
Utilizzi ffi.cast("fn_ptr_type", luaFunc) per creare callback compatibili con C. Conservi sempre un riferimento per impedire la raccolta da parte del GC. I callback non possono effettuare yield. Utilizzi gli upvalue per passare il contesto ai callback.
Domande Frequenti
La lezione «Callback: passaggio di funzioni Lua a C» è gratuita?
Sì — il testo completo di «Callback: passaggio di funzioni Lua a C» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Lua Academy, passa a CoddyKit PRO. Il corso Lua Academy include 4 lezioni in totale.
Cosa imparerò in «Callback: passaggio di funzioni Lua a C»?
Utilizzi ffi.cast per creare callback C che richiamano codice Lua. Eserciti Lua Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Lua Academy?
Non è richiesta alcuna esperienza precedente. Lua Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Callback: passaggio di funzioni Lua a C»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Lua Academy?
Sì. Ogni lezione Lua Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Nozioni di base sulla FFI: ffi.cdef e ffi.load
- Chiamata delle funzioni C tramite FFI
- Puntatori, struct e array nella FFI
- Callback: passaggio di funzioni Lua a C