Question

J'utilise Visual Studio 2005.

------------------------ [luapassing.cpp] ------------------ -

#include "lua.h"
static int myCfunc (Lua_State *L){
   double trouble = lua_tonumber(L,1);
   lua_pushnumber(L,16.0 -trouble);
   return 1;
}
int luaopen_luapassing (Lua_State *L){
   static const lua_reg Map [] = {{"dothis",myCfunc},{NULL,NULL}};
   luaL_register(L,"cstuff",Map);
   return;
}

------------------------- [csample.lua] ----------------- --------

package.cpath = "./CLua2.dll"
require "luapassing"

print("hola")
print(seth.doThis(120))
Était-ce utile?

La solution

Je vois plusieurs problèmes. Je vais les décrire et vous fournir un fragment de code qui devrait fonctionner car je pense que vous vouliez utiliser cet exemple.

Votre premier problème est que le compilateur C ++ a mutilé le nom de la seule fonction exportée de votre DLL dont le nom est important pour Lua: luaopen_luapassing () . La distribution binaire de stock pour Windows a été compilée en tant que programme C et prend un nom de style C pour le point d’entrée du module de la DLL.

De plus, le protocole de la fonction luaopen_x est légèrement incorrect. La fonction retourne un entier indiquant à Lua combien d'éléments au sommet de la pile de Lua retournent des valeurs que Lua doit utiliser. Le protocole supposé par require préférerait que vous laissiez l'objet table du nouveau module au-dessus de la pile et le renvoyiez à Lua. Pour ce faire, la fonction luaopen_x utilise habituellement luaL_register () comme vous l'avez fait, puis renvoie 1.

Il y a aussi la question du nommage. Les modules écrits en Lua pur ont l’occasion d’être moins conscients de leurs noms. Mais les modules écrits en C doivent exporter une fonction de la DLL qui inclut le nom du module dans son nom. Ils doivent également fournir ce nom de module à luaL_register () afin que la table appropriée soit créée et mise à jour dans l'environnement global. Enfin, le script client Lua verra le module chargé dans une table globale nommée comme le nom transmis à require , qui est également renvoyé par require afin qu'il puisse être mis en cache dans un local dans ce script.

Quelques autres nits avec le code C sont que le type numérique doit être orthographié lua_Number pour la portabilité, et qu'il serait conventionnel d'utiliser luaL_checknumber () plutôt que lua_tonumber () pour appliquer l’argument requis à la fonction. Personnellement, je nommerais l'implémentation C d'une fonction publique avec un nom en rapport avec son nom qui sera connu publiquement de Lua, mais ce n'est qu'une question de goût.

Cette version du côté C devrait résoudre ces problèmes:

#include "lua.h"
static int my_dothis (Lua_State *L){
   lua_Number trouble = luaL_checknumber(L,1);
   lua_pushnumber(L,16.0 -trouble);
   return 1;
}
extern "C" int luaopen_luapassing (Lua_State *L){
    static const lua_reg Map [] = {
        {"dothis", my_dothis},
        {NULL,NULL}
    };
    luaL_register(L,"luapassing",Map);
    return 1;
}

L'exemple de script doit ensuite faire référence au module chargé par son nom propre et aux fonctions définies par ce module par leurs noms propres. Lua est sensible à la casse. Ainsi, si le module crée une fonction nommée dothis () , le script doit utiliser le même nom et ne peut pas le trouver nommé doThis () , par exemple. exemple.

require "luapassing"

print("hola")
print(luapassing.dothis(120))

Je devrais ajouter que je n'ai pas encore compilé et exécuté ce qui précède, il pourrait donc rester une faute de frappe ou deux à la suite d'un exercice; -)

Autres conseils

Si vous envisagez de faire beaucoup de liaisons C ++ à lua, jetez un oeil à luabind .

Si vous compilez en tant que C ++ et souhaitez faire correspondre une interface "C", vous devez déclarer les fonctions visibles de l'extérieur comme extern "C" pour éviter les mutilations de noms.

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