Lua C++ Binding



  • Hallo Leute.

    Ich will Teile einer C++ Anwendung Scriptbar machen und wollte dazu Lua nehmen. Das ganze funktioniert soweit auch - aber wie genau macht ihr die Interaktion von Lua mit C++ und umgekehrt?

    Prinzipiell will ich dem Lua Script von der Anwendung aus einige Daten zur Verfuegung stellen und das Luascript soll dann einige Funktionen aufrufen koennen.

    Danach verarbeite ich die Ausgabe von Lua in C++ weiter.

    Es gibt ja einige Wrapper um Lua um die Bindings mit C++ zu erleichtern. Lohnen die sich, bzw. wenn ja: welcher ist der beste?

    Oder ist es praktischer direkt die Lua API dazu zu verwenden? Was sind eure Erfahrungswerte hier?

    PS:
    Lohnt sich SWIG hier eigentlich? Denn nett aussehen tut es ja...


  • Administrator

    Da bisher niemand was gesagt hat, melde ich mich mal. Ich möchte aber anmerken, dass ich bisher nicht all zu viel mit C++ und Lua gemacht habe. Ich habe bisher meistens von C# aus Lua integriert.

    Shade Of Mine schrieb:

    ... aber wie genau macht ihr die Interaktion von Lua mit C++ und umgekehrt?

    Prinzipiell will ich dem Lua Script von der Anwendung aus einige Daten zur Verfuegung stellen und das Luascript soll dann einige Funktionen aufrufen koennen.

    Danach verarbeite ich die Ausgabe von Lua in C++ weiter.

    In dem du Lua halt entsprechende Daten zur Verfügung stellst. Du kannst einem Lua Skript alles mögliche übergeben. Es gibt auch extra Userdata und C Functions. Ein Userdata hat wie eine Tabelle eine eigene Metatabelle für das Aufrufen von Methoden und Operatoren. Dadurch kannst du ein C++ Objekt übergeben und in Lua verwenden, wenn du die Klasse korrekt als Metatabelle übergibst.

    Shade Of Mine schrieb:

    Es gibt ja einige Wrapper um Lua um die Bindings mit C++ zu erleichtern. Lohnen die sich, bzw. wenn ja: welcher ist der beste?

    Oft empfohlen wird LuaBind. Bietet einem sehr viele Möglichkeiten C++ Funktionen und Klassen, bzw. Objekte, einfach in Lua Skripte einzubinden. So ein Wrapper nimmt einem enorm viel Arbeit ab. Wenn du die C++ Objekte selbst wrappen würdest, wäre das verdammt viel Arbeit. Eine Lua C Funktion erhält nur einen Parameter, nämlich einen Stack, worauf die übergebenen Parameter abgelegt sind. Man muss somit die Parameter prüfen und dann entsprechend die korrekte Funktion aufrufen. Für Überladung musst du nochmals Code schreiben, welcher die Fälle anhand der übergebenen Parametertypen unterscheidet. LuaBind macht dies alles bereits völlig automatisch über Templates für dich.

    Überflieg nur mal die Codebeispiele von LuaBind, dann merkst du schnell, wie verdammt einfach dies dank dem Wrapper wird:
    http://www.rasterbar.com/products/luabind/docs.html

    Shade Of Mine schrieb:

    Lohnt sich SWIG hier eigentlich? Denn nett aussehen tut es ja...

    Zu SWIG kann ich nichts sagen, da ich keine Erfahrungen mit SWIG habe.

    Grüssli



  • Vielen Dank, LuaBind werde ich mir näher ansehen.

    Ich habe inzwischen einige Tests mit SWIG gemacht - der generiert aber enorm viel Code - das ist mir etwas suspekt... Dafür ist der Aufwand sehr gering.

    Gibt es sonst noch Erfahrungen mit Lua in C++?

    Mir geht es weniger um eine konkrete Lösung als generell Erfahrungen und Ansätze die ihr verwendet.



  • Es gibt ja einige Wrapper um Lua um die Bindings mit C++ zu erleichtern. Lohnen die sich, bzw. wenn ja: welcher ist der beste?

    Nein, fuer mich lohnten sie sich nicht. Ich habe die LuaAPI direkt benutzt, ist aber aufwendiger.

    Das bedeuted konkret, dass du wrapping und unwrapping selbst implementieren musst. Jede Methode wird in eine "C-Funktion" umgeschrieben und dafuer ein Luawrapperfunktion definiert. Als ersten Parameter nimmt sie einen Zeiger auf das entsprechende Objekt. Innerhalb von Lua wird dieser Zeiger als light user data herumgereicht. Um Objekte anzubilden, werden Methoden/Funktionen in Tabellen gruppiert, damit ist es auch moeglich Vererbung zu modellieren.

    Der Artikel in Games Programming Gems 6: Binding C/C++ Objects to Lua hat mir damals den Einstieg erleichtert.



  • Du kannst dir evtl. Siedler 5 oder Worms (Mayhem) ansehen. Beide
    steuern den KI über Lua.

    0x0ERROR



  • 0x0ERROR schrieb:

    Du kannst dir evtl. Siedler 5 oder Worms (Mayhem) ansehen. Beide
    steuern den KI über Lua.

    Hilfreichster Post Ever 😉

    Trotzdem danke.


  • Administrator

    knivil schrieb:

    Nein, fuer mich lohnten sie sich nicht. Ich habe die LuaAPI direkt benutzt, ist aber aufwendiger.

    Sind diese zwei Sätze nicht irgendwie widersprüchlich?
    Ich meine LuaBind lohnt sich schon nur für das Einbinden von einer einzigen Funktion.

    knivil schrieb:

    Innerhalb von Lua wird dieser Zeiger als light user data herumgereicht.

    Ich empfehle auf Light Userdata eher zu verzichten, da sie keine Metatabellen haben können. Lieber ein Userdata nehmen, welches die grösse eines Zeigers hat und darin dann den entsprechenden Zeiger speichern. Schon nur damit man die zusätzliche __gc Metamethode hat, macht dies reizvoll.
    Dank LuaBind kann man das aber auch alles vergessen, da es für einem automatisch erledigt wird.

    Grüssli



  • Gut, hier ein Nachtrag: Es ist sehr lange her, dass ich Lua + C++ benutzt habe. Ich habe keine Ahnung, wie der Stand der Tools heute ist. Damals waren sie fuer mich unbefriediegend. Warum, tja leider ist es schon etwa 6 Jahre her. Wenn light userdata keine Metatabellen verwenden kann, dann habe ich kein light user data verwendet. Den Quelltext habe ich leider nicht mehr um nachzusehen. Aber da du garbage collection erwaehnst, ich wollte/musste das selbst in die Hand nehmen.



  • hallo,

    ich hätte zu diesem thema auch mal eine frage:

    0x0ERROR schrieb:

    Du kannst dir evtl. Siedler 5 oder Worms (Mayhem) ansehen. Beide
    steuern den KI über Lua.

    0x0ERROR

    ich nehme an, dass diese spiele einen eingebauten script-interpreter haben? oder wie wird das sonst gemacht? ich hab ein script, das z.b. npcs steuert.

    soweit ich übrigens weiß, wird für sowas auch mal python verwendet.

    warum schreibst du dir nicht einfach selbst einen interpreter?



  • Ja, wenn ich ein Auto will, baue ich mir auch einfach selbst eins!


  • Administrator

    pythonnnn schrieb:

    ich nehme an, dass diese spiele einen eingebauten script-interpreter haben? oder wie wird das sonst gemacht?

    Ja, die haben einen eingebauten Script-Interpreter. Lua ist z.B. darauf ausgelegt, dass man es in ein anderes Programm einbinden kann.

    pythonnnn schrieb:

    soweit ich übrigens weiß, wird für sowas auch mal python verwendet.

    Ja, z.B. Civilisation hatte Python eingesetzt. Aber das spielt hier keine grosse Rolle, da Shade Of Mine anscheinend Lua nehmen will.

    pythonnnn schrieb:

    warum schreibst du dir nicht einfach selbst einen interpreter?

    Gegenfrage: Wieso diese Menge an Zusatzaufwand betreiben, wenn man fix fertige Lösungen nehmen kann?

    Grüssli



  • Dravere schrieb:

    Ja, z.B. Civilisation hatte Python eingesetzt. Aber das spielt hier keine grosse Rolle, da Shade Of Mine anscheinend Lua nehmen will.

    Prinzipiell bin ich offen für alternativen - aber ich brauche nur etwas minimales was sehr schnell starten soll. Und da ich kaum Features brauche, bietet Lua alles was ich brauche:
    Simple Einbindung in meine Anwendung
    Wenig Memory Footprint
    Schnelles Initialisieren des Interpreters

    Ich habe mir auch Pawn angesehen, wie Rapso in einem anderen Thread mal vorgeschlagen hat - aber da war mir die Doku zu wenig. Im zweifelsfall nehme ich lieber die Standardlösung. Und das scheint Lua zu sein.

    Python wäre mir zu fett.

    PS:
    Mir geht es um den allgemeinen Ansatz. Die konkrete Implementierung ist dann der nächste Schritt. Mein aktueller Punkt ist: was sind die generellen Ansätze für diese Aufgabenstellung.

    Wie gesagt: ich starte auf eine gewisse Useraction sehr oft und sehr viele Lua-Scripte die jeweils minimal und trivial sind. Oft tun sie garnichts anderes als nur ein print() aufzurufen.


  • Administrator

    Shade Of Mine schrieb:

    Wie gesagt: ich starte auf eine gewisse Useraction sehr oft und sehr viele Lua-Scripte die jeweils minimal und trivial sind. Oft tun sie garnichts anderes als nur ein print() aufzurufen.

    Wirlich direkt ein print() aufrufen? Du hattest gesagt, dass du die Daten aus Lua danach weiterverarbeiten willst, oder? Wieso stellst du dann nicht eine API in Lua zur Verfügung? Über die API kann man Daten aus dem Programm holen, welche zur Verfügung gestellt werden, man kann aber auch wieder Daten zurückgeben.

    Die API kannst du über C++ Funktionen und Objekte per LuaBind den Lua Skripts zur Verfügung stellen.

    Grüssli



  • ok, also dann halt keinen eigenen interpreter 🙄

    allerdings könnten von der arbeit andere leute profitieren, wenn es anscheinend keinen gescheiten interpreter/parser gibt.

    mal schaun... der erste schritt wäre, dass man sich die sprache genau anschaut. gibt es eine art "sprach-standard" wie bei c?
    wo find ich den für lua? und wo für python? hab schon ein bissl gegoogelt, konnte aber nix in die richtung finden.

    Ethon schrieb:

    Ja, wenn ich ein Auto will, baue ich mir auch einfach selbst eins!

    Dravere schrieb:

    Gegenfrage: Wieso diese Menge an Zusatzaufwand betreiben, wenn man fix fertige Lösungen nehmen kann?

    Gegenfrage: Was mache ich mal in 30 jahren, wenn es keinen treiber/keine software mehr für meinen digitalen-"video-auf-pc-übertrag"-player mehr gibt? ich schreib mir selbst software. deshalb lernt man doch programmieren. um selbst was zu schaffen.



  • Im professionellen Bereich gibt es Deadlines. Und warum soll es fuer jeden scheiss einen Iso/IEEE/whatever-Standard wie bei C geben, wenn sowieso nur einer es implementiert?



  • Dravere schrieb:

    Wirlich direkt ein print() aufrufen? Du hattest gesagt, dass du die Daten aus Lua danach weiterverarbeiten willst, oder? Wieso stellst du dann nicht eine API in Lua zur Verfügung? Über die API kann man Daten aus dem Programm holen, welche zur Verfügung gestellt werden, man kann aber auch wieder Daten zurückgeben.

    Die API kannst du über C++ Funktionen und Objekte per LuaBind den Lua Skripts zur Verfügung stellen.

    Ein eigenes print natürlich.
    Und wie gesagt: die meisten Scripte brauchen da nicht viel. Aber es gibt wenige Scripte wo es dann notwendig ist die Daten zu transformieren und zu bearbeiten. Das kommt selten vor, ist aber wichtig dass es möglich ist.

    Prinzipiell generiert mir Lua Textdateien die weiter verarbeitet werden. Oft ist es ein Textblock der Fix ist, dann macht das Script nur print("Lorem ipsum...") aber ab und zu ist es notwendig dass es generierte Daten (die aus dem C++ teil kommen) als Ausgangsmaterial nutzen muss.

    So übergibt C++ zB eine liste an Lua, und Lua formt diese dann entsprechend um, um wieder reinen text zu bekommen. Da gibt es eine Menge an Infos die theoretisch Lua zur Verfügung stehen müssen - auch wenn nur ein sehr kleiner Teil der Scripte diese nutzen wird.


  • Administrator

    lua sprachstandard? schrieb:

    allerdings könnten von der arbeit andere leute profitieren, wenn es anscheinend keinen gescheiten interpreter/parser gibt.

    Wer sagt denn, dass es keinen guten Interpreter/Parser gibt?

    lua sprachstandard? schrieb:

    mal schaun... der erste schritt wäre, dass man sich die sprache genau anschaut. gibt es eine art "sprach-standard" wie bei c?
    wo find ich den für lua? und wo für python? hab schon ein bissl gegoogelt, konnte aber nix in die richtung finden.

    Deine Suchfähigkeiten sind ziemlich schlecht.
    http://www.lua.org/
    http://python.org/

    lua sprachstandard? schrieb:

    Gegenfrage: Was mache ich mal in 30 jahren, wenn es keinen treiber/keine software mehr für meinen digitalen-"video-auf-pc-übertrag"-player mehr gibt? ich schreib mir selbst software. deshalb lernt man doch programmieren. um selbst was zu schaffen.

    Das hat überhaupt nichts mit der aktuellen Aufgabenstellung zu tun. Und schreibst du alle Software selbst? Auch dein Betriebsystem? Oder nutzt du Bibliotheken, damit du nicht alles selbst machen muss?

    @Shade Of Mine,
    Wo genau liegt denn aktuell noch das Problem? Deine zwei Fragen sind somit:
    Wrapper verwenden?
    Welcher Wrapper verwenden?

    Um mehr geht es nicht, oder?

    Grüssli



  • Dravere schrieb:

    @Shade Of Mine,
    Wo genau liegt denn aktuell noch das Problem? Deine zwei Fragen sind somit:
    Wrapper verwenden?
    Welcher Wrapper verwenden?

    Um mehr geht es nicht, oder?

    Es geht um den generellen Ansatz. Keine konkreten Probleme. Eine Minimallösung mit direkt der Lua API und ein kleiner SWIG Test haben schon funktioniert.

    Mich interessiert hier lediglich was so die gängigen Varianten sind, das anzugehen. Ob sich so schwergewichte wie SWIG lohnen - oder ob man lieber alles direkt mit der Lua-C-API machen sollte.

    Ich habe noch nie Lua in C++ eingebettet und will daher eine Designtechnisch korrekte Lösung haben. Irgendwie zusammenpfuschen wäre ja kein Problem 😉



  • Es ist wie mit allem: Das erste Mal kriegt man es nie richtig hin.



  • knivil schrieb:

    Es ist wie mit allem: Das erste Mal kriegt man es nie richtig hin.

    exakt 😉
    deshalb der thread.
    damit die Lösung wenigstens keine ist, für die man sich schämen muss...


Anmelden zum Antworten