Fonctions de rappel : transmettre des fonctions Lua à C
Utilisez ffi.cast pour créer des fonctions de rappel C qui rappellent du code Lua.
Fonctions de rappel : transmettre des fonctions Lua à C est une leçon Lua Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Lua Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Lua Academy comprend 4 leçons au total.
Que sont les rappels C ?
Certaines API C exigent que vous transmettiez un pointeur de fonction que le code C appellera en retour. La ffi.cast de la FFI permet de créer des pointeurs de fonctions compatibles avec C à partir de fonctions Lua.
Déclarer un type de rappel
Commencez par déclarer le type de pointeur de fonction dans cdef.
local ffi = require("ffi")
ffi.cdef[[
typedef void (*callback_t)(int event, void *data);
void register_handler(callback_t cb);
]]Créer un rappel
Utilisez ffi.cast("callback_t", luaFunc) pour envelopper une fonction Lua comme rappel C. Le résultat est un pointeur de fonction C qui peut être transmis au code C.
local function myHandler(event, data)
print("Event:", event)
end
local cb = ffi.cast("callback_t", myHandler)
lib.register_handler(cb)Durée de vie des rappels
Conservez une référence Lua vers l’objet de rappel (cb). S’il est récupéré par le GC, l’appel du pointeur de fonction C provoquera un plantage. Stockez-le dans une variable ou une table ayant une longue durée de vie.
local callbacks = {} -- prevent GC
callbacks[#callbacks+1] = ffi.cast("callback_t", myHandler)
lib.register_handler(callbacks[#callbacks])Trier avec un comparateur C
Transmettez un comparateur Lua à qsort de C via un rappel 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] .. " ") endRappels et coroutines
Les rappels Lua appelés depuis C ne peuvent pas céder l’exécution (appeler coroutine.yield). Le côté C ne prend pas en charge le changement de coroutine de Lua. Concevez les rappels de manière à ce qu’ils ne cèdent pas l’exécution.
Upvalues dans les rappels
Les rappels Lua peuvent capturer normalement des upvalues. Cela permet aux rappels d’accéder à un contexte (par exemple, un objet ou une table d’état) sans utiliser de variables globales.
local function makeHandler(ctx)
return ffi.cast("callback_t", function(event, _)
ctx.lastEvent = event -- upvalue access
end)
endGestionnaires de signaux
Enregistrez des fonctions Lua comme gestionnaires de signaux Unix via la FFI. Soyez prudent : les gestionnaires de signaux sont soumis à de sévères restrictions quant aux fonctions C qu’ils peuvent appeler.
Gestion de la mémoire des rappels
Libérez les rappels avec cb:free() après les avoir désenregistrés du côté C. Les objets de rappel qui fuient gaspillent de la mémoire.
Alternative : fonctions d’encapsulation en C
Pour les intégrations complexes, une fine couche d’adaptation en C peut être plus claire que des rappels FFI. Cette couche rappelle Lua via l’API C, ce qui offre un contrôle total sur les coroutines et la gestion des erreurs.
Performances
Les rappels FFI sont rapides, mais pas autant que les appels FFI directs, car le pont de C vers Lua entraîne une surcharge de préparation. Pour les rappels très fréquents (par exemple, en audio), envisagez des implémentations entièrement en C.
Question sur les fonctions de rappel
Pourquoi devez-vous conserver une référence Lua vers un objet de fonction de rappel FFI ?
Récapitulatif : fonctions de rappel FFI
Utilisez ffi.cast("fn_ptr_type", luaFunc) pour créer des fonctions de rappel compatibles avec C. Conservez toujours une référence pour empêcher le ramasse-miettes de les libérer. Les fonctions de rappel ne peuvent pas utiliser yield. Utilisez des valeurs externes pour transmettre le contexte aux fonctions de rappel.
Questions Fréquemment Posées
La leçon « Fonctions de rappel : transmettre des fonctions Lua à C » est-elle gratuite ?
Oui — le texte complet de « Fonctions de rappel : transmettre des fonctions Lua à C » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Lua Academy, passe à CoddyKit PRO. Le cours Lua Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Fonctions de rappel : transmettre des fonctions Lua à C » ?
Utilisez ffi.cast pour créer des fonctions de rappel C qui rappellent du code Lua. Tu pratiques Lua Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Lua Academy ?
Aucune expérience préalable n'est requise. Lua Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.
Combien de temps prend la leçon « Fonctions de rappel : transmettre des fonctions Lua à C » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Lua Academy ?
Oui. Chaque leçon Lua Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Notions de base sur FFI : ffi.cdef et ffi.load
- Appeler des fonctions C via FFI
- Pointeurs, structures et tableaux en FFI
- Fonctions de rappel : transmettre des fonctions Lua à C