Question

Je travaille actuellement sur la mise en œuvre Lua dans l'une des applications que je travaille. Actuellement, je suis juste en utilisant le C api et l'enregistrement à l'aide des fonctions lua_register, mais je voudrais être en mesure de passer des pointeurs de fonction statiques et non statiques à certaines méthodes de classe.

J'ai trouvé certaines bibliothèques sur le net, mais depuis que je besoin de très peu de la fonctionnalité d'ensemble ils fournissent, je me demandais s'il y a un moyen facile de le faire.

Merci.

Était-ce utile?

La solution

Une API de bibliothèque complexe peut souvent être enveloppé rapidement et (presque) complètement en utilisant SWIG . L'avantage d'utiliser SWIG dans ce cas est qu'il est facile de construire des emballages à base de SWIG qui permettent l'utilisation de la bibliothèque , mais il a été écrit pour Lua 5.0. Je demande instamment à tous ceux qui utilisent sérieusement Lua de posséder une copie de l'édition actuelle du LIP.

Malheureusement, une zone où Lua 5.1 diffère le plus de 5,0 est dans le chargement dynamique des modules (à la fois C et Lua) avec require.

Voici un exemple complet (si petit) pour une bibliothèque C qui fonctionne en Lua 5.1. Nous commençons par la mise en œuvre de l'enveloppe dans un fichier 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;
}

Notez en particulier que la seule fonction qui est besoin d'être exportée luaopen_sm(), dont le nom doit correspondre au nom du module qui sera utilisé avec require, et le nom du fichier DLL. Avec ce fichier compilé en tant que sm.dll nommé DLL (probablement nommé libsm.so sur les systèmes Unix), il peut être chargé et utilisé dans un script Lua comme ceci:

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

Cet exemple, bien que non testé, devrait compiler et exécuter. Pour un exemple complet enveloppant la plupart des fonctions de math.h, voir la source au module math qui est distribué avec Lua. Parce que ces minces emballages contiennent beaucoup de code répétitif, des outils comme SWIG sont souvent capables de les créer donnés uniquement la déclaration de chaque fonction.

Méthodes d'emballage d'une classe C ++ est similaire en principe. Chaque fonction enveloppe Lua-appelable va avoir besoin d'un argument qui peut être mis en correspondance avec this sur le côté C, et il doit être mis en oeuvre soit comme une fonction de module statique ou une fonction membre statique qui localise également l'instance de l'objet cible, ainsi que les convertis les autres arguments. SWIG est particulièrement bien à la construction de ce type d'emballage et cache beaucoup de détails gores le long du chemin.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top