
Nos últimos dias precisei trabalhar com a interface entre códigos escritos em Lua e em C. Pesquisei um pouco sobre o assunto e pude perceber que apesar de um pouco complicada e de não ser tão bem documentada, a API de Lua para C funcionava muito bem. Resumidamente, a comunicação entre os programas se dá através de uma “pilha virtual”, acessada pelo programa em C. Cada elemento dessa pilha representa um valor de Lua, que pode ser utilizado em C através de funções de conversão como lua_tostring, ou lua_tonumber.
Até aí tudo bem. Alguns defeitos dessa interface começam a aparecer quando é preciso lidar com tipos de dados mais complexos, como tabelas em Lua, por exemplo. Abaixo está um trecho de czódigo em C para colocar uma tabela na pilha:
lua_newtable(L);
lua_pushstring(L,”indice1″);
lua_pushnumber(L,15);
lua_settable(L,2);
lua_pushstring(L,”indice2″);
lua_pushstring(L,”testedatabela”);
lua_settable(L,2);
Como é possível ver no código, é preciso dar um push no índice, outro push no valor e chamar a função lua_settable passando o índice da tabela na pilha como argumento para cada elemento. Para uma tabela com poucos elementos, não há complicações. O problema é quando esse procedimento precisa ser realizado para tabelas bem maiores.
Essa complicação toda me motivou a procurar como seria essa interface em outras linguagens. Acabei decidindo pesquisar uma solução em Python. Logo de cara já encontrei uma documentação muito mais clara e completa, e, no pouco tempo que passei estudando, tive a impressão de que a interface se dá de maneira bem mais simples. A função abaixo passa para o programa em Python um dicionário semelhante a tabela em Lua construída acima:
Py_BuildValue(”{siss}”,”indice1″,15,”indice2″,”testedatabela”);
A função Py_BuildValue é responsável pela comunicação com o código em Python. O funcionamento dela se dá através de strings de formatação, formadas por unidades de formatação que representam um objeto Python. Através dessas strings, é possível passar, sem maiores complicações, inteiros, strings, dicionários, listas e outros tipos de dados entre os programas em C e Python. Nesse exemplo, a string “{siss}” indica que o objeto Python gerado será um dicionário, e cada conjunto de dois valores em C consecutivos adiciona um item a esse dicionário.
Para mais detalhes, veja:
Lua/C API
Python/C API
A vantagem do Lua aparentemente é a eficiência. Embora haja mais chamadas de função para uma dada tarefa as funções não precisa fazer parsing de strings.
A forma lua também me parece mais UNIX like, ou seja, fornecer blocos pequenos que executem tarefas bem específicas, depois constroem-se uma camada em cima desses blocos, no caso nada impede do usuário criar uma função a lá printf que gera uma função similar à do Python, a assinatura seria (copiando a nomenclatura Python):
lua_buildvalue(char *fmt, …);
Onde fmt é uma string de format, que pode ser a mesma do Python, e o resto dos argumentos seriam os valores a serem colocados na tabela.
Complicado? Não bem documentado?
Que documentação é essa que você viu? Pela descrição com certeza não é a oficial.
A API de Lua com C é uma das mais simples e bem documentadas que há. Um bom lugar pra você começar é no PiL:
http://www.lua.org/pil/24.html
[]’s
Cacilhas, La Batalema
Olá Rodrigo, realmente o link que você postou possui boas informações, no entanto, ainda faltam algumas coisas como o mecanismo para definição de classes em c++ e utilização das mesmas em Lua.
Além deste link que você postou, a wiki dos usuários de Lua nos ajudou bastante.
Lua Users Wiki
Abs
Salve Rodrigo!
A documentação diz que Lua foi definido como C, portanto é preciso usar extern “C” ao incluir seus cabelhos em C++.
extern “C” {
#include “lua.h”
#include “lualib.h”
#include “lauxlib.h”
}
No mais, o uso de Lua em C++ é como o uso de socket, unistd e outras bibliotecas C.
[]’s
Cacilhas, La Batalema
Salve!
Sobre os externs, isso já foi feito
O que quis dizer é que a biblioteca padrão não fornece meios (simples) para você definir uma classe em C++ e exportá-la para que um arquivo lua possa acessá-la.
Para isso, usei a biblioteca lunar, disponível na wiki do lua-users (http://lua-users.org/wiki/CppBindingWithLunar) que por sinal é muito muito útil.
Abs
wow !!
its very interesting article.
Nice post.
realy gj
thx