0Pricing
Lua Academy · Aula

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] .. " ") end

Callbacks 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)
end

Manipuladores 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

  1. Noções básicas de FFI: ffi.cdef e ffi.load
  2. Chamando funções C via FFI
  3. Ponteiros, estruturas e matrizes em FFI
  4. Retornos de chamada: passando funções Lua para C
← Voltar para Lua Academy