📦 Sistema de Módulos (CTEC)

Como funciona a importação, carregamento de DLLs e ciclo de vida.

🔧

Arquitetura de Carregamento

O sistema de módulos do Sol (implementado no kernel loadlib.ctec) gerencia como scripts (.sol) e bibliotecas nativas (.dll/.so) são carregados e executados.

Módulo vs Pacote: Qual a diferença?

É comum confundir os termos, mas em Sol eles têm significados específicos:

TermoSignificado
Módulo É o código que você escreve e importa. Um arquivo .sol ou .dll é um módulo.
Ex: "texto", "meu_jogo.player"
Pacote É a biblioteca (pacote) que gerencia o sistema de carregamento. Ela não é um "folder" de módulos, mas sim o gerenciador que sabe onde encontrar e como carregar os arquivos.
💡 Resumo: Você cria módulos e usa a biblioteca pacote para configurar onde encontrá-los.

Ciclo de Vida da Importação

Quando você executa importe("meu_modulo"), o Sol segue estes passos exatos:

  1. Verificação de Cache: Procura em pacote.carregados. Se encontrar, retorna o valor imediatamente (módulo não é reexecutado).
  2. Busca (Searchers): Percorre a lista pacote.buscadores para encontrar quem sabe carregar o módulo:
    • 1. Pré-carga: Verifica pacote.precarga (módulos embutidos).
    • 2. Sol Loader: Procura arquivos .sol nos caminhos de pacote.caminho.
    • 3. C Loader: Procura bibliotecas dinâmicas (.dll, .so) em pacote.caminho_c.
    • 4. C Root: Procura bibliotecas "root" (para módulos aninhados como a.b.c).
  3. Carregamento e Execução:
    • Para .sol: Compila e executa o script. O valor retornado (ex: tabela) é o resultado.
    • Para .dll/.so: Carrega a binário na memória (via LoadLibrary/dlopen) e chama a função de inicialização (solopen_nome).
  4. Cache: O resultado é salvo em pacote.carregados["meu_modulo"].

Tipos de Módulos Suportados

ExtensãoTipoComo é carregadoUso
.sol Script Sol Compilado e executado na VM Lógica de negócio, aplicações normais
.dll (Win)
.so (Linux)
Biblioteca Dinâmica Carregamento nativo (OS) Bibliotecas de alta performance, acesso a hardware
.o / .a Objeto Estático ❌ Não suportado dinamicamente Devem ser linkados ao executável na compilação do interpretador

Importando Bibliotecas Nativas (CTEC)

Bibliotecas escritas em C/C++ (CTEC) são compiladas para .dll ou .so. O Sol procura uma função de entrada específica:

-- Ao fazer: importe("minha_lib")
-- O Sol procura a função C exportada: solopen_minha_lib(sol_State *L)

Criando Módulos Nativos (CTEC) — Passo a Passo

Resumo rápido: o módulo nativo deve exportar a função solopen_nome (visível no export table). Use Atributo((Exporte)) ou um .def e linke contra libsol.a quando usar APIs do runtime.

  1. Escreva o código CTEC
    /* Exemplo mínimo (CTEC) */
    #Inclua "sol.int"
    Fixo Inteiro minha_saudacao(sol_State *L) { (Vazio)L; printf("hello world\n"); Retorne 0; }
    
    Atributo((Exporte)) SOLMOD_API Inteiro solopen_minha_lib(sol_State *L) {
        sol_newlib(L, (sol_Reg[]){ {"saudacao", minha_saudacao}, {NULL,NULL} });
        Retorne 1;
    }
    
  2. Compilar/Linkar (Windows)
    cd teste_modulo
    ctec -I.. testemodulo.ctec ..\libsol.a -shared -o testemodulo.dll
    ctec -impdef testemodulo.dll -v   -- verifica exports (.def)
  3. Teste em tempo de execução
    -- Rode a partir da pasta onde a DLL está localizada
    ..\sol.exe run_testemodulo.sol
    -- ou ajuste pacote.caminho_c para incluir a pasta da DLL
  4. Dicas rápidas
    • Atributo de export: use Atributo((Exporte)) em solopen_* para garantir que o símbolo apareça em Windows.
    • Linkagem: linkar ..\libsol.a evita símbolos indefinidos (ex.: sol_newlib).
    • Verificação: rode ctec -impdef sua.dll -v ou use dumpbin /EXPORTS para checar o export table.
    • Execução: se importe() não encontrar o módulo, execute sol.exe a partir do diretório da DLL ou copie a DLL para um dos caminhos de busca.

Configurando Caminhos Nativos

Para o Sol encontrar suas DLLs, configure pacote.caminho_c (note o _c):

-- Adicionar pasta 'bin' para buscar DLLs
pacote.caminho_c = pacote.caminho_c .. ";./bin/?.dll"

Variáveis de Controle

O pacote pacote expõe tabelas que controlam todo o processo:

Diferenças Importantes

⚠️ Atenção: Módulos .o e .a são estáticos. Eles não podem ser carregados com importe(). Se você tem código nessas extensões, precisa compilá-los junto com o interpretador Sol ou transformá-los em uma DLL compartilhada.
Entender este ciclo permite criar arquiteturas complexas e plugins misturando Sol e C!
```