2011-08-02 99 views
0

我有一个C++程序,我已经使用luabind绑定到Lua。我目前正在测试lua和luabind必须提供的错误处理方法,以帮助在路上调试lua脚本。当语法错误和编程错误出现时,我们的目标是让luabind或lua抛出异常,以便我可以调试并纠正它们。C++不捕捉lua异常

现在,问题是,下面的脚本只是停止执行没有任何错误消息或异常被抛出,所以在一个更大的程序中,我不知道问题出在哪里,或者即使有问题第一名。

下面是相关片段:

的Lua:(start.lua)

--complete file shown, this is meant to test the error handling of the C++ program 
print("This is valid") 
print(1234) 
bad_function() 
a = "meow" 
b = 7 
c = a + b 

C++:

Engine *callbackEngine; 
int theCallback(lua_State *L) //This is so I can use my own function as an 
           //exception handler, pcall_log() 
{ 
    return callbackEngine->pcall_log(L); 
} 

void Engine::Run() 
{ 
    luabind::set_pcall_callback(&theCallback); //my own callback function, 
               //redirects to 
               //pcall_log() below 
try { 
    luaL_dofile(L, "scripts/start.lua"); 
} 
catch(luabind::error &sError) { //This never gets executed, noted by breakpoints 
    theCallback(L); 
} 
//etc...code not shown 

int Engine::pcall_log(lua_State *L) 
{ 
    lua_Debug d; 
    lua_getstack(L,1,&d); 
    lua_getinfo(L, "Sln", &d); 
    lua_pop(L, 1); 
    stringstream ss; 
    ss.clear(); 
    ss.str(""); 
    ss << d.short_src; 
    ss << ": "; 
    ss << d.currentline; 
    ss << ": "; 
    if (d.name != 0) 
    { 
     ss << d.namewhat; 
     ss << " "; 
     ss << d.name; 
     ss << ") "; 
    } 
    ss << lua_tostring(L, -1); 
    logger->log(ss.str().c_str(),ELL_ERROR); 
    return 1; 
} 

这里是运行时的输出:

This is valid 
1234 

脚本停止运行抛出像我预期的异常。有没有办法控制lua抛出异常或其他方式来处理错误?我将日志记录功能设置为产生调试信息,但是断点显示上述catch语句没有执行。

谢谢!

回答

2

如果你想通过加载一个Luabind Lua中,那么你就不能使用luaL_dofile或其他常规Lua函数去做吧。你必须使用Luabind功能。所以这看起来像这样:

namespace lb = luabind; 
int luaError = luaL_loadfile(pLuaState, "scripts/start.lua"); 
//Check for errors 

lb::object compiledScript(lb::from_stack(pLuaState, -1)); 
lb::call_function<void>(compiledScript); //Call the script. 

lua_pop(pLuaState, 1); //Remove the script from the stack. It's stored in our luabind::object 
+0

那么,你可以'lua_pcall'块,但你不能指望一个C++异常。 Luabind'runtime'是不是简单地将'what()'异常消息放在Lua栈上并调用'lua_error'?这是我对文档的期望,以及在简单测试中似乎会发生的情况。 (然而,使用'luabind :: call_function'可以让异常通过然而。) –

+0

@Brian:Luabind不会完全无效Lua API。它只是包装它的一部分。但是,如果您确实需要获取字符串Luabind样式,则可以使用'luabind :: from_stack'将堆栈条目转换为'luabind :: object'。 –

+0

谢谢,这个作品!当脚本遇到错误时,它现在会根据需要路由到我的回调函数。它也会在发生错误后崩溃主机程序。仍然看着这个... – Brian

2

luaL_dofile()不是Luabind的一部分,所以我不会期望它的任何Luabind例外。您设置的处理程序在Luabind本身从Lua调用某些内容时使用/传递(使用pcall())。 luaL_dofile()是基本Lua代码(L后缀将其标记为库包装以简化调用)和普通C的一部分,所以您必须自行完成错误处理(从未在Lua/Luabind中使用异常)。呼叫。

未经检验的,但下面的代码应该做你希望你的代码做什么:

if(!luaL_doFile(L, "scripts/start.lua")) 
    theCallback(L);