lua-users home
lua-l archive

Re: Calling Lua from C - have I been doing it wrongly?

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


lua_error function is supposed to be called from a protected call, and
all luaL_check* functions call it. Instead you can check the stack
safely with calls to lua_is* and other similar functions. That way you
don't have to add an additionnal pcall layer. Example:
int main()
{
 lua_State* L = luaL_newstate();
 luaL_openlibs(L);
 lua_pushcfunction(L, foo);
 if (lua_pcall(L, 0, 1, 0)==0)
 {
 if (lua_isstring(L, -1)) /* <-- This call is entirely safe,
whatever foo returned */
 {
 /* Process returned string */
 }
 }
}
2006年10月14日, David Burgess <dburgess@gmail.com>:
> So really, the whole sequence above should be protected itself by
> another level of lua_pcall, like I described. Am I right?
Right.
Refer to the usage of lua_cpcall() in lua.c.
Also if you are using in a Windows GUI app. you might want to
change the default panic function using lua_atpanic() to
a routine that uses MessageBox() (or whatever). The default
function uses fprintf()/fputs().
db
On 10/15/06, Nick Gammon <nick@gammon.com.au> wrote:
> After recent questions about is it "safe" to use Lua, and a couple of
> application crashes of my own, I am starting to wonder if I have been
> doing it 100% correctly.
>
> There is an example in the PIL book (Listing 24.1) along these lines
> (I have slightly simplified it):
>
> ---------------
> #include "lua.h"
> #include "lauxlib.h"
>
> char buff [] = "print 'hi'";
>
> int main (void)
> {
> lua_State * L = luaL_newstate ();
> luaL_openlibs (L);
> int error = luaL_loadbuffer(L, buff, strlen(buff), "line") ||
> lua_pcall(L, 0, 0, 0);
> return 0;
> } // end of main
> ---------------
>
> Isn't there a problem here? What if luaL_loadbuffer fails? For
> example, out of memory? We can simulate a failure with this example
> program, which in essence does what caused my application to crash
> recently:
>
> ---------------
> #include "lua.h"
> #include "lauxlib.h"
> #include <stdio.h>
>
> int main (void)
> {
> lua_State * L = luaL_newstate ();
> lua_pushnil (L);
> luaL_checkstring (L, -1); --> error, string not on stack
> printf ("Hello, world\n");
> return 0;
> } // end of main
> ---------------
>
> If I run this at the command-line I get this message:
>
> PANIC: unprotected error in call to Lua API (bad argument #-1 (string
> expected, got nil))
>
>
> If I run the equivalent code in my (Windows GUI) application it
> crashes the application with some sort of error in Lua5.1.dll.
>
>
> Would the correct method be to always wrap any attempts to use the
> Lua functions into a protected environment? - like in this example:
>
> ---------------
> #include "lua.h"
> #include "lauxlib.h"
> #include <stdio.h>
>
> // do things here that might fail
> int stub(lua_State *L)
> {
> lua_pushnil (L);
> luaL_checkstring (L, -1);
> }
>
> int main (void)
> {
> lua_State * L = luaL_newstate ();
> lua_pushcfunction (L, stub);
> int error = lua_pcall (L, 0, 0, 0);
> printf ("stub returned %i\n", error);
> printf ("Hello, world\n");
> return 0;
> } // end of main
> ---------------
>
>
> I am familiar with doing lua_pcall to run the code that I ultimately
> want to run in a safe way, but I usually did something like this:
>
> lua_getglobal (L, "somefunction"); --> get some function
> lua_pushstring (L, "blah blah"); --> push arguments to function
> lua_pcall (L, 1, 1, 0); --> call the function
> const char * p = lua_checkstring (L, -1); --> oops! this might fail
>
>
> So really, the whole sequence above should be protected itself by
> another level of lua_pcall, like I described. Am I right?
>
> - Nick
>

AltStyle によって変換されたページ (->オリジナル) /