2009-04-24 6 views
3

Gibt es eine Möglichkeit festzustellen, wie viele Parameter eine Lua-Funktion dauert, bevor sie aus C/C++ - Code aufgerufen wird?Gibt es eine Möglichkeit programmgesteuert in C/C++ zu ermitteln, wie viele Parameter eine Lua-Funktion erwartet?

Ich sah lua_Debug und lua_getinfo, aber sie scheinen nicht zu bieten, was ich brauche.

Es mag ein bisschen wie ich bin gegen den Geist von Lua gehen, aber ich möchte wirklich die Schnittstelle, die ich zwischen Lua und C++ haben kugelsicher. Wenn eine C++ - Funktion aus Lua-Code aufgerufen wird, überprüft die Schnittstelle, ob Lua die richtige Anzahl von Argumenten geliefert hat und der Typ jedes Arguments korrekt ist. Wenn ein Problem mit den Argumenten gefunden wird, wird eine lua_error ausgegeben.

Ich möchte ähnliche Fehler haben, die anders herum überprüfen. Wenn C++ eine Lua-Funktion aufruft, sollte zumindest überprüft werden, ob die Lua-Funktion mehr Parameter als nötig deklariert.

Antwort

5

Was Sie verlangen, ist in Lua nicht möglich.

Sie können eine Lua-Funktion mit einer Reihe von Argumenten wie folgt definieren:

function f(a, b, c) 
    body 
end 

jedoch erlegt Lua keine Beschränkungen für die Anzahl der Argumente, die Sie an diese Funktion übergeben.

Dies gilt:

f(1,2,3,4,5) 

Die zusätzlichen Parameter werden ignoriert.

Dies gilt auch:

f(1) 

Die übrigen Argumente zugeordnet sind 'Null'.

Schließlich können Sie definiert eine Funktion, die eine variable Anzahl von Argumenten entgegennimmt:

function f(a, ...) 

an welcher Stelle Sie eine beliebige Anzahl von Argumenten an die Funktion übergeben können.

Siehe Abschnitt 2.5.9 der Lua reference manual.

Das Beste, was Sie hier tun können, ist das Hinzufügen von Überprüfungen zu Ihren Lua-Funktionen, um zu überprüfen, ob Sie die erwarteten Argumente erhalten.

+0

Nun, ich sagte, ich weiß, was ich tue, ist nicht im Geiste von Lua :) Mit Funktionen implementiert und vollständig innerhalb von Lua aufgerufen wird es so funktionieren, wie Sie sagen, aber was ich will, ist ein Weg zur Stärkung der Lua/C++ Schnittstelle. Wenn Sie eine C++ - Schnittstelle implementieren, die Lua-Funktionen verwendet (unter Verwendung unseres benutzerdefinierten Lua/C++ - Bindungssystems), ist es sinnvoll, automatisch zu erzwingen, dass die von C++ aufgerufenen Lua-Funktionen die korrekte Anzahl von Argumenten implementieren. Das heißt ich vermute, dass es nicht möglich ist, zu tun, was ich will. Dachte ich würde trotzdem fragen! –

1

Nein, nicht im Standard Lua. Und Aaron Saarela sagt, dass es etwas außerhalb des Geistes von Lua ist, so wie ich es verstehe. Der Lua-Weg wäre, sicherzustellen, dass die Funktion selbst nil als einen vernünftigen Standard behandelt (oder sie in einen vernünftigen Standard mit etwas wie name = name or "Bruce" vor ihrer ersten Verwendung konvertiert) oder wenn es keinen vernünftigen Standard gibt, sollte die Funktion entweder einen Fehler werfen oder einen Fehler zurückgeben (if not name then error"Name required" end ist eine allgemeine Redewendung für die erstere und if not name then return nil, "name required" end ist eine allgemeine Redewendung für die letztere). Indem die Lua-Seite für ihre eigenen Argumentprüfungen verantwortlich gemacht wird, erhalten Sie diesen Vorteil unabhängig davon, ob die Funktion von Lua oder C aufgerufen wird. Das heißt, es ist möglich, dass Ihre Module eine Attributtabelle pflegen können, die von der Funktion indiziert wird enthält die Informationen, die Sie wissen müssen. Es würde natürlich Wartung erfordern. Es ist auch möglich, dass MetaLua verwendet werden kann, um Syntaxzucker hinzuzufügen, um die Tabelle direkt aus Funktionsdeklarationen zur Kompilierzeit zu erstellen.Bevor Sie die Lua-Funktion aufrufen, würden Sie sie direkt verwenden, um alle verfügbaren Attribute zu suchen und sie zum Überprüfen des Aufrufs zu verwenden.

Wenn Sie besorgt über kugel Proofing sind, möchten Sie vielleicht die Funktion Umgebung kontrollieren mit einiger Vorsicht zu verwenden, was (wenn überhaupt) Globals zum Lua Seite zur Verfügung stehen, und verwenden lua_pcall() anstatt lua_call(), so dass Sie jede fangen geworfene Fehler.

2

Ich würde dies nicht auf der Lua-Seite tun, außer Sie haben die volle Kontrolle über den Lua-Code, den Sie validieren. Es ist ziemlich üblich, dass Lua-Funktionen zusätzliche Argumente ignorieren, indem sie sie einfach weglassen.

Ein Beispiel ist, wenn wir nicht einige Methoden implementieren wollen, und eine Stub-Funktion:

function do_nothing() end 

full_api = {} 
function full_api:callback(a1, a2) print(a1, a2) end 

lazy_impl = {} 
lazy_impl.callback = do_nothing 

Dies ermöglicht (und ein wenig Leistung) zu speichern Eingabe von verfügbaren Funktionen wiederverwendet.

Wenn Sie weiterhin eine Funktionsargumentvalidierung durchführen möchten, müssen Sie den Code statisch analysieren. Ein Werkzeug, um dies zu tun ist Metalua.

+2

Danke. Ich werde Metalua betrachten. Die statische Analyse des Lua-Codes könnte in meinem Fall tatsächlich besser sein, als zu versuchen, die Überprüfung zur Laufzeit durchzuführen. –

+0

Gern geschehen. Wenn Sie dies tun, wenden Sie sich bitte an die Mailing-Liste von Metalua (http://lists.llaaforge.net/mailman/listinfo/metalua-list). Es ist wahrscheinlich, dass Sie einen wertvollen Rat von Metalua Autor erhalten werden. –

1

Die von Ihnen angeforderten Informationen sind nicht in allen Fällen verfügbar. Zum Beispiel könnte eine Lua-Funktion tatsächlich in C als lua_CFunction implementiert werden. Aus dem Lua-Code gibt es keine Möglichkeit, eine reine Lua-Funktion von einer lua_CFunction zu unterscheiden. Und im Fall einer lua_CFunction wird die Anzahl der Parameter überhaupt nicht angezeigt, da sie vollständig davon abhängt, wie die Funktion implementiert wird.

Auf der anderen Seite, was Sie tun können, ist ein System für Funktionen Autoren (sei es in reinem Lua oder in C), um zu werben, wie viele Parameter ihre Funktionen erwarten. Nach dem Erstellen der Funktion (Funktion f (a, b, c) Ende) würden sie es einfach an eine globale Funktion übergeben (register (f, 3)). Sie wären dann in der Lage, diese Informationen aus Ihrem C++ - Code abzurufen, und wenn die Funktion ihre Parameter nicht ankündigte, dann greifen Sie auf das zurück, was Sie jetzt haben. Mit einem solchen System könnte man sogar den Typ propagieren, der von den Parametern erwartet wird.

+0

Sie haben ein paar gute Punkte gemacht. Obwohl das System, das Sie im zweiten Absatz vorschlagen, für menschliche Fehler genauso offen ist wie der Standardfall, müssen Sie sich im Normalfall auf den Coder verlassen, um die Argumente richtig zu machen, im zweiten Fall muss der Coder beides richtig machen die Argumente und die Argument-Metadaten. –

4

Sie können die Anzahl der Parameter, Upvalues ​​und ob die Funktion eine variable Anzahl von Argumenten in Lua 5.2 akzeptiert, indem Sie den 'u' Typ verwenden, um nups, nparams, isvararg fields by get_info() zu füllen. Diese Funktion ist in Lua 5.1 nicht verfügbar.