尝试调用Lua脚本时出现“Error: attempt to call a nil value”错误。

我试图从C++调用一个lua函数,并不断收到错误消息“错误:尝试调用空值”。

lua函数创建一个C++对象,然后调用其方法,粘合代码已经生成为tolua++。在调用lua函数时,我传递了一个lua_State指针,因为C++类需要一个用于其构造函数的指针,而lua函数将其传递给它。

但是据我所知,它从来没有那么远,它根本不会运行脚本。至少错误没有引用脚本中的任何行号。

这里是调用函数的C++代码:

int main()
{

lua_State *lState;

lState = luaL_newstate(); //new lua state
tolua_TestClass_open (lState); //open libs for TestClass

int iStatus = luaL_loadfile( lState, "lua1.lua" ); //load script
if (iStatus)
{
    std::cout << "Error: " << lua_tostring( lState, -1 );
    return 1;
}

iStatus = lua_pcall( lState, 0, 0, 0); //initialise the lua script
if( iStatus )
{
    std::cout << "Error: " << lua_tostring( lState, -1 );
    return 1;
}

lua_getglobal( lState, "lua1Function" ); //starting the function call
lua_pushlightuserdata (lState, lState); //lState is also being passed in as a parameter

iStatus = lua_pcall( lState, 1, 0, 0 ); //calling on this lua state with 1 argument expecting 0 outputs
if( iStatus ) //error checking
{
    std::cout << "Error: " << lua_tostring( lState, -1 );
    return 1;
}

return 1;
}

这里是lua脚本:

function lua1Function(lstate)
tclass = TestClass:new();
tclass:method1();
tclass:method3();
end

我相当确定它不是像忘记做这样的简单事情:

tclass = TestClass:new(lstate);

因为粘合代码似乎表明我不需要那样做,在这里:

/* method: new of class  TestClass */
#ifndef TOLUA_DISABLE_tolua_TestClass_TestClass_new00
static int tolua_TestClass_TestClass_new00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
 tolua_Error tolua_err;
 if (
     !tolua_isusertable(tolua_S,1,"TestClass",0,&tolua_err) ||
     !tolua_isnoobj(tolua_S,2,&tolua_err)
 )
  goto tolua_lerror;
 else
#endif
 {
  lua_State* tolua_var_1 =  tolua_S; //seems to know I want the lua_State by default,
//usually it will pop a usertype or luanumber or whatever off the stack,
//depending on the parameter
  {
   TestClass* tolua_ret = (TestClass*)  Mtolua_new((TestClass)(tolua_var_1));
    tolua_pushusertype(tolua_S,(void*)tolua_ret,"TestClass");
  }
 }
 return 1;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
 return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE

错误消息THAT似乎证实了我的理论:“在函数'new'中出错。第二个参数是'userdata'; '\ [no object ]'是期望的。”即它没有期望/不需要我传递那个lua_State指针

我不知所措,我很难找到有关lua的问题的解决方案,因为与tolua++有关的教程/文档似乎很少,但现在为时已晚更改绑定库。

任何帮助将不胜感激,我希望我已经提供了足够的诊断问题。

编辑:这是我的TestClass.cpp代码(您可以忽略method1,2和3,因为由于此错误似乎不会调用它们):

#include "TestClass.h"
#include <iostream>

TestClass::TestClass(lua_State *L)
{
    num = NULL;
    lState = L;
}

int TestClass::method1()
{
    int iStatus = luaL_loadfile( lState, "lua2.lua" );
    if (iStatus)
    {
        std::cout << "Error: " << lua_tostring( lState, -1 );
        return 1;
    }

    iStatus = lua_pcall( lState, 0, 0, 0); //this might be to initialise the lua script
    if( iStatus )
    {
        std::cout << "Error: " << lua_tostring( lState, -1 );
        return 1;
    }

    ///////////call lua function, passing on self pointer onto the stack////////////////

    lua_getglobal( lState, "lua2Function" );
    tolua_pushusertype(lState, this, "TestClass");

    iStatus = lua_pcall( lState, 1, 1, 0 );
    if( iStatus ) //error checking
    {
        std::cout << "Error: " << lua_tostring( lState, -1 );
        return 1;
    }

    ///////////lua function returns an int, return it//

原文链接 https://stackoverflow.com/questions/5559741

点赞
stackoverflow用户298661
stackoverflow用户298661

Lua 状态永远不会被 Lua 代码显式地处理-它是隐式的。由 Lua 调用的任何 C++ 函数都不需要显式地传递状态-它作为第一个参数传递,而这个参数始终由 Lua 传递,无论其他参数是什么,因为没有 lua_State* 就无法以任何方式与 Lua 交互。唯一的原因是如果你有某种元状态,或者,如果你正在处理 Lua 的协作协同文件。

全局函数看起来足够简单,不太可能是错误的源头。你需要打印 TestClass 的内容来验证它是否具有预期的内容,如果不是,那么这是绑定库特定的问题,你将不得不深入研究其内部,因为那段代码看起来最有可能的问题是 TestClass 表没有你预期的内容。

2011-04-06 12:45:04
stackoverflow用户693891
stackoverflow用户693891

原文:

It turns out the only problem was that "lua2Function" was spelt with a lower-case F in the script. The code as I've pasted it actually works fine. How thoroughly embarrassing!

I guess I've learnt that tolua++ definitely DOES take care of passing lua_State pointers into methods, at least.

翻译:

结果发现问题只是在脚本中“lua2Function”被小写字母F拼写错误。而我粘贴的代码实际上能够正常工作。真是尴尬!

我想我已经学到了tolua++ 肯定会处理将 lua_State 指针传递到方法中这一点。
2011-04-06 17:04:20