Domanda

Al momento sto lavorando per l'attuazione Lua in una delle applicazioni che sto lavorando. Attualmente sto usando solo l'API C e registrare le funzioni utilizzando lua_register, ma mi piacerebbe essere in grado di passare puntatori a funzione statica statici e non a certi metodi di classe.

Ho trovato alcune librerie in rete, ma da quando ho bisogno di molto poco della funzionalità complessiva che forniscono Mi chiedevo se c'è un modo semplice per farlo.

Grazie.

È stato utile?

Soluzione

Un API biblioteca complesso può spesso essere avvolto rapidamente e (quasi) completamente con SWIG . Un vantaggio di utilizzare SWIG in questo caso è che è facile da costruire involucri SWIG-based che consentono l'uso della biblioteca in 18 lingue principali compreso Lua, Perl, Python, Ruby e Java, tra gli altri.

Se Lua è il vostro preferito (e forse unica) preoccupazione, poi mi consiglia imparare ad usare luaL_register() al centro di una strategia per costruire moduli Lua in C. un vantaggio della costruzione di un modulo in questo modo è che si mantiene tutte le funzioni in un unico spazio dei nomi, senza alcun sovraccarico. Sarà necessario per realizzare una funzione wrapper che corrisponde la convenzione funzione chiamante Lua C (proprio come si fa con lua_register()) e che raccoglie gli argomenti Lua dalla pila, chiama la funzione avvolto, e spinge qualsiasi valore di ritorno e fuori i parametri al Lua stack. Una buona panoramica di come andare su questo si possono trovare nella programmazione libro in Lua. La copia online della prima edizione discute la creazione di biblioteca in Capitolo 26 , ma è stato scritto per Lua 5.0. Esorto vivamente a chiunque seriamente utilizzando Lua di possedere una copia della corrente edizione della PiL.

Sfortunatamente, un'area in cui Lua 5.1 differisce più di 5,0 è nel caricamento dinamico di moduli (sia C e Lua) con require.

Ecco un completo (anche se piccola) ad esempio per una libreria C che opera in Lua 5.1. Si comincia con l'attuazione del involucro in un file C:

#include <lua.h>
#include <luaxlib.h>
#include <math.h>
#undef PI
#define PI (3.14159265358979323846)

static int l_sin (lua_State *L) {
    double r = luaL_checknumber(L,1);
    lua_pushnumber(L, sin(r));
    return 1;
}

static int l_cos (lua_State *L) {
    double r = luaL_checknumber(L,1);
    lua_pushnumber(L, cos(r));
    return 1;
}

static const struct luaL_reg smlib [] = {
    {"sin", l_sin},
    {"cos", l_cos},
    {NULL, NULL}  /* sentinel */
};

int luaopen_sm (lua_State *L) {
    luaL_openlib(L, "sm", smlib, 0);
    lua_pushnumber(L,PI);
    lua_rawset(L,-2,"pi");
    return 1;
}

Si noti in particolare, che l'unica funzione che hanno bisogno di essere esportato è luaopen_sm(), il cui nome deve corrispondere al nome del modulo che verrà utilizzato con require, e con il nome del file DLL. Con questo file compilato come una DLL di nome sm.dll (probabilmente chiamato libsm.so su sistemi Unix-like), allora può essere caricato e utilizzato in uno script Lua come questo:

require "sm"
print(sm.sin(sm.pi/3), sm.cos(sm.pi/3));

In questo esempio, anche se non testato, deve compilare ed eseguire. Per un esempio completo avvolgimento maggior parte delle funzioni da math.h, vedere la sorgente al modulo math che è distribuito con Lua. Poiché questi sottili involucri contengono un sacco di codice ripetitivo, strumenti come SWIG sono spesso in grado di crearli dato solo la dichiarazione di ogni funzione.

metodi di confezionamento di una classe C ++ è simile in linea di principio. Ogni funzione involucro Lua richiamabili avrà bisogno di un argomento che può essere mappata in this sul lato C ++, e deve essere attuato sia come funzione modulo statico o funzione membro statica che individua anche l'istanza di oggetto di destinazione e convertiti gli altri argomenti. SWIG è particolarmente bravo a costruire questo tipo di involucro e nasconde un sacco di dettagli scabrosi lungo la strada.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top