http://game.gpihome.eu/PureBasic/lua/
Wozu braucht man LUA?
Lua ist wie gesagt eine Scriptsprache. World of Warcraft nutzt diese bspw. um die Addonschnittstelle zu realisieren. Wenn man teile des Programmcodes in LUA realisiert oder "Hook"-Schnittstellen schafft, kann so jeder ein Spiel/Programm in verhalten verändern und erweitern. Eine andere Anwendungsmöglichkeit wären bspw. Konfigurationsdateien, die auch Rechnungen und Bedingungen enthalten können. Gibt sicherlich viele Anwendungsmöglichkeiten. Man stelle sich vor, man könnte den PureBasic-Compiler sagen: alles was zwischen den Codewörtern "Class" und "EndClass" steht soll erstmal an ein LUA-Script weitergegeben werden....
Zudem ist LUA für fast alle Plattformen erhältlich - naja in der Theorie, dazu später mehr
Bitte beachten, vollständig getestet ist das ganze nicht, ein Fehler kann immer irgendwo sein!
Ich hab auch gleich einen unschönen Bug in PureBasic gefunden:
Wenn man PrototypeC mit Quads verwendet:
PrototypeC.q function()
wird nur ein 16Bit-Wert zurückgegeben, der rest wird verworfen. Bei 64Bit ist das noch kein Problem, hier nimmt man einfach Integer (ist ja gleich groß), da gehts. Bei 32Bit ist das ganze nicht so schön.
Die Routinen sind für Windows geschrieben und von der LUA.DLL liegt auch eine 32Bit und 64Bit Version vor. Für Linux liegt eine 64Bit-Bibliothek in so-Format vor, aber da ich kein Linux habe, komplett ungetestet! Für Macs hab ich überhaupt nichts gefunden. Gedownloaded wurden die DLL/SO von http://luabinaries.sourceforge.net/index.html
In Example-Ordner gibt es ein paar Beispiele:
Example1:
Einfaches Beispiel wie man eine Lua-Datei aus den Datenblock lädt und aufruft. Und wie man eine Funktion aus den LUA-Script nachträglich ausführt.
Example2:
Wie man mit Metatabellen schreibt und so eine eigene Bibliothek schreibt und mit Userdata eigene Daten in LUA einspeisen kann.
Example3:
Leider ist es etwas Trickreich, wenn man die Standard-Bibliotheken von LUA sperren will. Gerade die io und os Bibliothek ermöglichen den Zugriff auf jede Datei auf den Rechner. Das kann ungewünscht sein, bspw. wenn man die LUA-Scripte zwingen will, in einem bestimmten Verzeichnis Daten abzulegen. Die Methode lässt sich auch durch ein "os = require('os')" in LUA-Script nicht mehr aushebeln. Alternativ müsste man LUA selbst compilen und die Bibliotheken kürzen. Da ich aber zukünftig einfach eine Binary downloaden will, ist mir die Methode lieber
Zudem werden hier drei Lua-Scripte in die gleiche VM geladen und ausgeführt, dabei werden die Script-Adressen zum ausführen in einer LUA-Tabelle gespeichert - eine bessere Methode gibts in Example5. Ich hab die Methode nur mal drin gelassen, falls jemand mal mit Tabellen handtieren will.
Example4:
Lädt eine LUA-Datei und speichert diese dann in binär-form ab. Anschließend wird in einer neuen VM die binärdatei eingelesen und ausgeführt. LUA benutzt (wie java) einen Pseudobinärcode. Durch diese Methode erreicht man zweierlei: Erstes muss der Quellcode nicht mehr compiled werden und zweitens er ist nicht mehr so leicht änderbar.
Example5:
Lädt mehrere LUA-Scripte in eine "VM" und führt diese aus. Zu beachten ist, das jedes Script in einen Chunk geladen wird und man nur einen Chunk einzeln starten kann. Die Adressen des Chunks (in Prinzip ist das wie eine Adresse einer Funktion) wird dabei in der #LUA_REGISTRYINDEX hinterlegt. Das Problem bei der Kommunikation mit LUA ist, das es Datenformate in LUA gibt, die es so nicht in PB gibt. Bspw eine Adresse zu einer LUA-Funktion. Man kann aber diese Adresse in der #LUA_REGISTRYINDEX speichern (hat nichts mit der Windows-Registry zu tun!) und bekommt einen Handle zurück - ähnlich wie bei Purebasic mit #pb_any. Das kann man dann verwenden und in PB speichern.
Example6:
Eine simple grafische Demo. Ich hab die Beispielbilder von PB genommen, so das ich keine reinkopieren brauchte Kann man sicher noch ausbauen, bspw. das LUA-Script in einen eigenen Task endlos laufen lassen.
In der Zip sind zwei pbi:
module_lua.pbi
diese muss man einfach einbinden und mit UseModule "anmelden" und mittels lua_initalize() starten:
Code: Alles auswählen
XIncludeFile "module_lua.pbi"
UseModule lua
If Lua_Initialize()=#False
End
EndIf
....
Lua_Dispose()
module_lua_extern.pbi
die module_lua_extern.pbi ist ein kleiner Trick, der mir sehr viel Schreibarbeit abnimmt. Die DLL wird mittels Prototypen in PureBasic eingebunden. Der Nachteil ist, das man die Prototypen und Global - deklarationen in DeclareModule unterbringen muss, aber die Zuweisung in Module-Block. Zudem wollte ich das bei lua_dispose() die ganzen funktionen auf die Adresse 0 verweisen und nicht irgendwo in Speicher, wo die DLL war. Lieber ein sauberer Absturz, als wenn willkürlich eine Funktion versehentlich aufgerufen wird. In schlimmsten Fall funktioniert das ganze sogar noch...
So, mehr fällt mir jetzt gerade nicht ein Sorry fürs etwas wirr schreiben, bei Fragen einfach fragen.
Hier noch ein paar Links zum einlesen:
https://www.lua.org/
http://www.fh-wedel.de/~si/seminare/ws0 ... a/lua0.htm