Retornos de chamada: passando funções Lua para C
Use ffi.cast para criar retornos de chamada C que chamem código Lua.
Retornos de chamada: passando funções Lua para C é uma aula grátis de Lua Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Lua Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Lua Academy inclui 4 aulas no total.
O que são callbacks C?
Algumas APIs C exigem que você passe um ponteiro de função que o código C chamará de volta. O ffi.cast da FFI permite criar ponteiros de função compatíveis com C a partir de funções Lua.
Declarando um tipo de callback
Primeiro, declare o tipo de ponteiro de função em cdef.
local ffi = require("ffi")
ffi.cdef[[
typedef void (*callback_t)(int event, void *data);
void register_handler(callback_t cb);
]]Criando um callback
Use ffi.cast("callback_t", luaFunc) para encapsular uma função Lua como um callback C. O resultado é um ponteiro de função C que pode ser passado ao código C.
local function myHandler(event, data)
print("Event:", event)
end
local cb = ffi.cast("callback_t", myHandler)
lib.register_handler(cb)Tempo de vida de um callback
Mantenha uma referência Lua ao objeto de callback (cb). Se ele for coletado pelo GC, chamar o ponteiro de função C causará uma falha. Armazene-o em uma variável ou tabela de longa duração.
local callbacks = {} -- prevent GC
callbacks[#callbacks+1] = ffi.cast("callback_t", myHandler)
lib.register_handler(callbacks[#callbacks])Ordenando com um comparador C
Passe um comparador Lua para o qsort de C por meio de um callback da 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] .. " ") endCallbacks e corrotinas
Callbacks Lua chamados por C não podem produzir uma suspensão (chamar coroutine.yield). O lado C não oferece suporte à troca de corrotinas do Lua. Projete callbacks que não produzam suspensões.
Upvalues em callbacks
Callbacks Lua podem capturar upvalues normalmente. Isso permite que acessem o contexto (por exemplo, um objeto ou uma tabela de estado) sem variáveis globais.
local function makeHandler(ctx)
return ffi.cast("callback_t", function(event, _)
ctx.lastEvent = event -- upvalue access
end)
endManipuladores de sinais
Registre funções Lua como manipuladores de sinais Unix por meio da FFI. Tenha cuidado: os manipuladores de sinais têm restrições severas sobre quais funções C podem chamar.
Gerenciamento de memória de callbacks
Libere callbacks com cb:free() depois de removê-los do lado C. Vazar objetos de callback desperdiça memória.
Alternativa: funções adaptadoras em C
Para integrações complexas, uma camada fina de adaptação em C pode ser mais adequada do que callbacks da FFI. Essa camada chama o Lua de volta pela API C, oferecendo controle total sobre corrotinas e tratamento de erros.
Desempenho
Callbacks da FFI são rápidos, mas não tanto quanto chamadas FFI diretas, pois a ponte de C para Lua envolve uma sobrecarga de preparação. Para callbacks de frequência muito alta (por exemplo, áudio), considere implementações totalmente em C.
Pergunta sobre retorno de chamada
Por que é necessário manter uma referência Lua a um objeto de retorno de chamada FFI?
Recapitulação: retornos de chamada FFI
Use ffi.cast("fn_ptr_type", luaFunc) para criar retornos de chamada compatíveis com C. Armazene sempre uma referência para impedir a coleta de lixo. Retornos de chamada não podem usar yield. Use valores capturados para passar contexto aos retornos de chamada.
Perguntas Frequentes
A aula “Retornos de chamada: passando funções Lua para C” é grátis?
Sim — o texto completo de “Retornos de chamada: passando funções Lua para C” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Lua Academy, atualize para CoddyKit PRO. O curso de Lua Academy inclui 4 aulas no total.
O que vou aprender em “Retornos de chamada: passando funções Lua para C”?
Use ffi.cast para criar retornos de chamada C que chamem código Lua. Você pratica Lua Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Lua Academy?
Nenhuma experiência prévia é necessária. Lua Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “Retornos de chamada: passando funções Lua para C”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Lua Academy?
Sim. Cada aula de Lua Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Noções básicas de FFI: ffi.cdef e ffi.load
- Chamando funções C via FFI
- Ponteiros, estruturas e matrizes em FFI
- Retornos de chamada: passando funções Lua para C