The luaL_ functions are convenience functions in the Lua C API. There's nothing in them that is primitive: nothing in luaL_* that can't be done using a few calls to lua_* functions.
luaL_dostring is a case in point. The manual page is short and to the point.
int luaL_dostring (lua_State *L, const char *str);
Loads and runs the given string. It is defined as the following macro:
(luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))
So the function basically does a load and and exec. That's not necessarily a bad thing, but you get some more options if you split load and exec. Specifically, you can load a big and complex lua script once, and then run it several times, without the overhead of parsing the string.It returns 0 if there are no errors or 1 in case of errors.
Of course, to do that you need to be able to fund the function once you've loaded it. luaL_loadstring is a convenience wrapper for lua_load (which is more complicated than most people will ever need), but you still need to look at lua_load to get the important datum:
Loads a Lua chunk. If there are no errors, lua_load
pushes the compiled chunk as a Lua function on top of the stack
A "chunk" is what lua calls the compiled bytecode resulting from a load operation. As the manual says , the chunk is typed as a function. So to make it happen you need to call it. Usually with lua_pcall. The "p" in pcall means "protected mode" which means that an error in the lua code can't crash the C++ program Generally, you want all your calls to use protected mode.So let's go back the simple hello program:
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
using namespace std;
#include <string>
#include <iostream>
int main()
{
int rc;
string prog = "print \"hello\"";
/*
* create a state for the lua interpretter
*/
lua_State *L = lua_open();
/*
* set up the standard lua libraries
*/
luaL_openlibs(L);
/*
* load the string: the compiled code will be left in a "chunk"
* (an anyonymous function) on the top of the stack
*/
rc = luaL_loadstring(L, prog.c_str());
if(rc == 1) {
cout << "there was an error loading the script: <<"
<< lua_tostring(L, -1)
<< ">>"
<< endl
;
}
/*
* call the chunk: it's on top of the stack
*/
rc = lua_pcall(
L, // lua state
0, // number of arguments
0, // number of expected args
0 // error handler - use lua default
);
lua_close(L);
return 0;
}
And that works. So now I can write
lua_pcall(L, 0, 0, 0);
lua_pcall(L, 0, 0, 0);
lua_pcall(L, 0, 0, 0);
And get "hello hello hello", right? Wrong. I get one "hello". The other two calls do nothing.
The problem is that the function has to be on top of the stack.The trouble is, to quote the manual:
All arguments and the function value are popped from the stack when the function is calledSo by calling the chunk, we've lost it. It presumably still lives somewhere deep inside the luaState data, but I don't know any way to retrieve it.
So what we need to do is to make a note of where we can find it before we make the call....
1 comment:
The spacing in your code example(s) makes them really hard to read.
Post a Comment