Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ &引用;错误:尝试调用nil值“0”;尝试调用lua脚本时_C++_Lua - Fatal编程技术网

C++ &引用;错误:尝试调用nil值“0”;尝试调用lua脚本时

C++ &引用;错误:尝试调用nil值“0”;尝试调用lua脚本时,c++,lua,C++,Lua,我试图从C++调用一个LUA函数,并且我不断地得到错误消息“错误:尝试调用一个零值”。 Lua函数创建C++对象,然后调用它的一种方法,用Telua++生成胶水代码。当调用Lua函数时,我传递到一个LuaAuthPosits指针,因为C++类需要一个构造函数,Lua函数使用它。 但据我所知,它从来没有走那么远,它根本没有运行脚本。至少错误没有引用脚本中的任何行号 这里是C++代码调用函数: int main() { lua_State *lState; lState = luaL_news

我试图从C++调用一个LUA函数,并且我不断地得到错误消息“错误:尝试调用一个零值”。

Lua函数创建C++对象,然后调用它的一种方法,用Telua++生成胶水代码。当调用Lua函数时,我传递到一个LuaAuthPosits指针,因为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;
}
我敢肯定,这不是像忘记做那样简单的事情:

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
产生的错误消息似乎证实了我的理论:“函数‘new’中的错误。参数#2是‘userdata’;‘不需要对象’。” i、 e.它不希望/不需要我传入lua_状态指针

我不知所措,我很难找到lua问题的解决方案,因为在tolua++领域,教程/文档似乎非常少,但现在更改绑定库已经太迟了

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

编辑:这是我的TestClass.cpp代码(您可能会忽略方法1、2和3,因为由于此错误,它们似乎没有被调用):

#包括“TestClass.h”
#包括
TestClass::TestClass(lua_状态*L)
{
num=NULL;
lState=L;
}
int TestClass::method1()
{
int-iStatus=luaL_加载文件(lState,“lua2.lua”);
如果(iStatus)
{

STU::CUT< P> Lua状态从未被Lua代码显式处理,它是隐式的。任何由LUA调用的C++函数不需要显式地传递状态,因为它是第一个参数,它总是由Lua传递,而不考虑其他参数,因为不可能与Lua交互,而不必使用<代码> LuaSuST。ate*
。这样做的唯一原因是,如果您有某种元状态,或者,如果您正在使用Lua的合作例程进行操作


全局函数似乎足够简单,不太可能是错误源。您需要打印TestClass的内容以验证它是否具有预期的内容,如果没有,则这是绑定库特有的问题,您必须深入研究其内部,因为在我看来,代码最有可能的问题是TestClaSS表不具有你所期望的它。

< P> Lua状态从未被Lua代码显式处理,它是隐式的。任何由Lua调用的C++函数不需要显式地传递状态,因为它是第一个参数,它总是由Lua传递,而不考虑其他参数,因为它是不可能的。e在没有
Lua\u状态*
的情况下以任何方式与Lua进行交互。这样做的唯一原因是如果您有某种元状态,或者如果您使用Lua的合作例程进行操作


全局函数似乎足够简单,不太可能是错误源。您需要打印TestClass的内容以验证它是否具有预期的内容,如果没有,则这是绑定库特有的问题,您必须深入研究其内部,因为在我看来,代码最有可能的问题是TestClass该表没有您期望的功能。

结果表明,唯一的问题是“lua2Function”在脚本中用小写字母F拼写。我粘贴的代码实际上运行良好。多么令人尴尬


我想我已经了解到,至少tolua++确实负责将lua_状态指针传递到方法中。

结果表明,唯一的问题是“lua2Function”在脚本中是用小写字母F拼写的。我粘贴的代码实际上工作得很好。多么令人尴尬啊


我想我已经了解到,至少tolua++确实会负责将lua_状态指针传递到方法中。

感谢您的回复,我编辑了这篇文章以包含TestClass.cpp代码。我之所以将lua_状态*参数传递到构造函数中,是因为我希望创建的对象将其存储为属性,这样它就可以使用它需要调用lua函数本身。在意识到tolua++生成的代码可能会在lua_状态下为我传递之前,我就提出了这个想法,因此我目前正在进行实验,看看是否可以在没有我的诡计的情况下运行类似的代码来尝试隔离问题。感谢您的回复,我已经编辑了这篇文章,以包含TestClass.cpp代码我之所以将lua_State*参数传递到构造函数中,是因为我希望创建的对象将其存储为属性,这样它就可以使用它来调用lua函数本身。在意识到tolua++生成的代码可能会以lua_状态传递给我之前,我提出了这个想法,所以我目前正在试验,看看是否可以获得similar代码在没有我的诡计的情况下运行,试图隔离问题。
/* 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
#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////////////
    num = lua_tointeger( lState, -1 );

    return 0;
}

int TestClass::method2(int i)
{
    i += 2;
    return i;
}

void TestClass::method3()
{
    std::cout << (char)num << std::endl;
}

/*
** Lua binding: TestClass
** Generated automatically by tolua++-1.0.92 on 04/05/11 17:59:24.
*/

#ifndef __cplusplus
#include "stdlib.h"
#endif
#include "string.h"

#include "tolua++.h"


/* function to release collected object via destructor */
#ifdef __cplusplus

static int tolua_collect_TestClass (lua_State* tolua_S)
{
 TestClass* self = (TestClass*) tolua_tousertype(tolua_S,1,0);
    Mtolua_delete(self);
    return 0;
}
#endif


/* function to register type */
static void tolua_reg_types (lua_State* tolua_S)
{
 tolua_usertype(tolua_S,"TestClass");
}

/* 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;
  {
   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

/* method: new_local of class  TestClass */
#ifndef TOLUA_DISABLE_tolua_TestClass_TestClass_new00_local
static int tolua_TestClass_TestClass_new00_local(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;
  {
   TestClass* tolua_ret = (TestClass*)  Mtolua_new((TestClass)(tolua_var_1));
    tolua_pushusertype(tolua_S,(void*)tolua_ret,"TestClass");
    tolua_register_gc(tolua_S,lua_gettop(tolua_S));
  }
 }
 return 1;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
 return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE

/* method: method1 of class  TestClass */
#ifndef TOLUA_DISABLE_tolua_TestClass_TestClass_method100
static int tolua_TestClass_TestClass_method100(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
 tolua_Error tolua_err;
 if (
     !tolua_isusertype(tolua_S,1,"TestClass",0,&tolua_err) ||
     !tolua_isnoobj(tolua_S,2,&tolua_err)
 )
  goto tolua_lerror;
 else
#endif
 {
  TestClass* self = (TestClass*)  tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
  if (!self) tolua_error(tolua_S,"invalid 'self' in function 'method1'", NULL);
#endif
  {
   int tolua_ret = (int)  self->method1();
   tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
  }
 }
 return 1;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'method1'.",&tolua_err);
 return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE

/* method: method2 of class  TestClass */
#ifndef TOLUA_DISABLE_tolua_TestClass_TestClass_method200
static int tolua_TestClass_TestClass_method200(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
 tolua_Error tolua_err;
 if (
     !tolua_isusertype(tolua_S,1,"TestClass",0,&tolua_err) ||
     !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
     !tolua_isnoobj(tolua_S,3,&tolua_err)
 )
  goto tolua_lerror;
 else
#endif
 {
  TestClass* self = (TestClass*)  tolua_tousertype(tolua_S,1,0);
  int tolua_var_2 = ((int)  tolua_tonumber(tolua_S,2,0));
#ifndef TOLUA_RELEASE
  if (!self) tolua_error(tolua_S,"invalid 'self' in function 'method2'", NULL);
#endif
  {
   int tolua_ret = (int)  self->method2(tolua_var_2);
   tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
  }
 }
 return 1;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'method2'.",&tolua_err);
 return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE

/* method: method3 of class  TestClass */
#ifndef TOLUA_DISABLE_tolua_TestClass_TestClass_method300
static int tolua_TestClass_TestClass_method300(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
 tolua_Error tolua_err;
 if (
   !tolua_isusertype(tolua_S,1,"TestClass",0,&tolua_err) ||
   !tolua_isnoobj(tolua_S,2,&tolua_err)
     )
  goto tolua_lerror;
 else
#endif
 {
  TestClass* self = (TestClass*)  tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
  if (!self) tolua_error(tolua_S,"invalid 'self' in function 'method3'", NULL);
#endif
  {
   self->method3();
  }
 }
 return 0;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'method3'.",&tolua_err);
 return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE

/* Open function */
TOLUA_API int tolua_TestClass_open (lua_State* tolua_S)
{
 tolua_open(tolua_S);
 tolua_reg_types(tolua_S);
 tolua_module(tolua_S,NULL,0);
 tolua_beginmodule(tolua_S,NULL);
  #ifdef __cplusplus
  tolua_cclass(tolua_S,"TestClass","TestClass","",tolua_collect_TestClass);
  #else
  tolua_cclass(tolua_S,"TestClass","TestClass","",NULL);
  #endif
  tolua_beginmodule(tolua_S,"TestClass");
   tolua_function(tolua_S,"new",tolua_TestClass_TestClass_new00);
   tolua_function(tolua_S,"new_local",tolua_TestClass_TestClass_new00_local);
   tolua_function(tolua_S,".call",tolua_TestClass_TestClass_new00_local);
   tolua_function(tolua_S,"method1",tolua_TestClass_TestClass_method100);
   tolua_function(tolua_S,"method2",tolua_TestClass_TestClass_method200);
   tolua_function(tolua_S,"method3",tolua_TestClass_TestClass_method300);
  tolua_endmodule(tolua_S);
 tolua_endmodule(tolua_S);
 return 1;
}


#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501
 TOLUA_API int luaopen_TestClass (lua_State* tolua_S) {
 return tolua_TestClass_open(tolua_S);
};
#endif