Wie bette ich ein Lua-Skript in eine C-Binärdatei ein?

8

Ich bin in der Shell-Welt verwöhnt worden, wo ich es tun kann:

%Vor%

Jetzt versuche ich, ein Lua-Skript in eine C-Anwendung aufzunehmen, von der ich erwarte, dass sie mit der Zeit wächst. Ich habe mit einem einfachen begonnen:

%Vor%

Aber das hat mehrere Nachteile. In erster Linie muss ich den Zeilenvorschüben und Zitaten entkommen. Aber jetzt treffe ich die string length ‘1234’ is greater than the length ‘509’ ISO C90 compilers are required to support Warnung, während ich mit gcc kompiliere und ich möchte dieses Programm nicht nur eigenständig, sondern auch portabel für andere Compiler behalten.

Was ist der beste Weg, ein großes Lua-Skript in ein C-Programm aufzunehmen und nicht als separate Datei an den Endbenutzer zu liefern? Im Idealfall möchte ich das Skript in eine separate * .lua-Datei verschieben, um das Testen und die Änderungskontrolle zu vereinfachen und diese Datei irgendwie in die ausführbare Datei zu kompilieren.

    
BMitch 30.05.2011, 03:02
quelle

2 Antworten

4

Ein wirklich billiger, aber nicht so einfach zu ändernder Weg ist es, etwas wie bin2c zu verwenden, um einen Header aus einer ausgewählten lua-Datei (oder seinem kompilierten Bytecode, der schneller und kleiner ist) zu erzeugen, und dann an lua zu übergeben ausführen.

Sie können auch versuchen, es als Ressource einzubetten, aber ich habe keine Ahnung, wie das außerhalb von Visual Studio / Windows funktioniert.

Je nachdem, was Sie tun möchten, finden Sie möglicherweise sogar exeLua .

    
Necrolis 30.05.2011, 10:06
quelle
11

Auf Systemen, die binutils unterstützen, können Sie auch eine Lua-Datei in eine .o-Datei mit 'ld -r' kompilieren, die .o-Datei mit einem gemeinsamen Objekt verknüpfen und dann Ihre Anwendung mit der gemeinsam genutzten Bibliothek verknüpfen. Zur Laufzeit dlsym (RTLD_DEFAULT, ...) im lua-Text und kann diese dann beliebig auswerten.

So erstellen Sie some_stuff.o aus some_stuff.lua:

%Vor%

Dadurch erhalten Sie eine Objektdatei mit Symbolen, die den Anfang, das Ende und die Größe Ihrer LUA-Daten begrenzen. Diese Symbole werden, soweit ich weiß, durch ld aus dem Dateinamen bestimmt. Sie haben keine Kontrolle über die Namen, aber sie werden konsistent abgeleitet. Sie erhalten etwas wie:

%Vor%

Verknüpfen Sie nun some_stuff.o wie jede andere Objektdatei in ein gemeinsames Objekt. Schreiben Sie dann in Ihre App eine Funktion, die den Namen "some_stuff_lua" trägt, und führen Sie die entsprechende dlsym-Magie aus. Etwas wie das folgende C ++, das davon ausgeht, dass Sie einen Wrapper um lua_State namens SomeLuaStateWrapper haben:

%Vor%

Wenn Sie nun innerhalb Ihrer Anwendung die Bibliothek mit some_stuff.o verbunden oder geöffnet haben, können Sie einfach sagen:

%Vor%

und der ursprüngliche Inhalt von some_stuff.lua wurde im Kontext von 'wrapper' lua_load'ed.

Wenn Sie außerdem möchten, dass die gemeinsam genutzte Bibliothek, die some_stuff.lua enthält, mit 'require' aus Lua geladen werden kann, geben Sie einfach dieselbe Bibliothek mit dem luaopen-Einstiegspunkt some_stuff.oa in einer anderen C / C ++ - Datei an :

%Vor%

Ihr eingebetteter Lua ist nun auch über require verfügbar. Dies funktioniert besonders gut mit luabind.

Mit SCons ist es ziemlich einfach, das Build-System so zu erziehen, dass es, wenn es eine .lua-Datei im Quellenteil einer SharedLibrary sieht, die Datei mit den obigen ld / objcopy-Schritten kompiliert:

%Vor%

Ich bin mir sicher, dass es möglich ist, so etwas mit anderen modernen Build-Systemen wie CMake zu machen.

Diese Technik ist natürlich nicht auf Lua beschränkt, sondern kann verwendet werden, um fast jede Ressource in einer Binärdatei einzubetten.

    
acm 30.05.2011 16:41
quelle

Tags und Links