Wie rufe ich C ++ Funktionen aus einem Lua-Script?
-
06-07-2019 - |
Frage
Ich bin mit 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))
Lösung
Ich sehe einige Probleme. Ich werde sie, beschreiben und ein Code-Fragment bereitzustellen, die funktionieren sollte, wie ich glaube, dass Sie dieses Beispiel soll arbeiten.
Ihr erstes Problem besteht darin, dass die C ++ Compiler den Name der einzigen Funktion aus der DLL, dessen Namen Angelegenheiten Lua exportierte verstümmelt: luaopen_luapassing()
. Die Aktie Binärdistribution für Windows wurde als C-Programm kompiliert wird, und nimmt einen C-Stil-Namen für den DLL-Modul Einstiegspunkt.
Außerdem müssen Sie das Protokoll für die luaopen_x
Funktion etwas falsch. Die Funktion gibt eine ganze Zahl, die Lua sagt, wie viele Elemente auf der Oberseite der Lua-Stapel sind die Rückgabewerte für die Verwendung von Lua. Das Protokoll von require
angenommen würde es vorziehen, dass Sie das neue Modul der Tabelle Objekt auf der Oberseite des Stapels verlassen und es zu Lua. Um dies zu tun, würde die luaopen_x
Funktion normalerweise verwenden luaL_register()
wie Sie taten, dann 1 zurück.
Es gibt auch die Frage der Namensgebung. Module in reiner Lua geschrieben hat die Möglichkeit, weniger über ihre Namen. Aber Module in C geschrieben hat eine Funktion aus dem DLL zu exportieren, die den Namen des Moduls in seinem Namen enthält. Sie haben auch den Modul Namen luaL_register()
zu schaffen, so dass die rechte Tabelle in der globalen Umgebung erstellt und aktualisiert. Schließlich wird der Client Lua Script das geladene Modul in einer globalen Tabelle wie die require
gaben Namen benannt sehen, die auch von require
zurückgeführt wird, so dass es in diesem Skript in einem lokalen Cache gespeichert werden kann.
Ein paar anderer nits mit dem C-Code sind, dass der numerische Typ wirklich lua_Number
für Portabilität geschrieben werden soll, und dass es wäre herkömmlich luaL_checknumber()
zu verwenden, anstatt lua_tonumber()
das erforderliche Argument an die Funktion zu erzwingen. Ich persönlich würde die C Implementierung einer öffentlichen Funktion Namen mit einem Namen zu seinem Namen im Zusammenhang, die öffentlich von Lua bekannt sein werden, aber das ist nur eine Frage des Geschmacks.
Diese Version der C-Seite sollte diese Probleme beheben:
#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;
}
Das Beispielskript muss dann in das bereits geladene Modul durch seinen richtigen Namen beziehen, und auf die von diesem Modul durch ihre Eigennamen definierten Funktionen. Lua ist Groß- und Kleinschreibung, so dass, wenn das Modul eine Funktion mit dem Namen dothis()
schafft, dann ist das Skript, das denselben Namen verwenden muß, und kann es nicht doThis()
finden, zum Beispiel genannt.
require "luapassing" print("hola") print(luapassing.dothis(120))
sollte ich hinzufügen, dass ich nicht wirklich die oben kompiliert und ausgeführt, so könnte es einen Tippfehler oder zwei links als Übung sein; -)
Andere Tipps
Wenn Sie vorhaben, eine Menge von C ++ zu tun LUA Bindung, Sie vielleicht einen Blick auf luabind .
Wenn Sie wie C ++ kompilieren und wollen eine ‚C‘ Schnittstelle entsprechen, sollen Sie die von außen sichtbaren Funktionen wie extern "C"
erklären zu Namensverkürzung zu vermeiden.