title: "Error: attempt to call a nil value" when trying to call lua script
body: <p>I'm trying to call a lua function from C++ and I keep getting the error message "Error: attempt to call a nil value".</p>
  
  <p>The lua function creates a C++ object and then calls one of its methods, the glue code has been generated with tolua++. When calling the lua function I pass in a lua_State pointer, as the C++ class needs one for its constructor, which the lua function hands to it.</p>
  
  <p>But as far as I can tell it never gets that far, it simply doesn't run the script at all. At least the error doesn't reference any line numbers in the script.</p>
  
  <p>Here is the C++ code calling the function:</p>
  
  <pre><code>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 &lt;&lt; "Error: " &lt;&lt; lua_tostring( lState, -1 );
      return 1;
  }
  
  iStatus = lua_pcall( lState, 0, 0, 0); //initialise the lua script
  if( iStatus )
  {
      std::cout &lt;&lt; "Error: " &lt;&lt; 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 &lt;&lt; "Error: " &lt;&lt; lua_tostring( lState, -1 );
      return 1;
  }
  
  return 1;
  }
  </code></pre>
  
  <p>Here is the lua script:</p>
  
  <pre><code>function lua1Function(lstate)
  tclass = TestClass:new();
  tclass:method1();
  tclass:method3();
  end
  </code></pre>
  
  <p>I'm fairly sure it's not something as simple as forgetting to do:</p>
  
  <pre><code>tclass = TestClass:new(lstate);
  </code></pre>
  
  <p>As the glue code seems to indicate I don't need to do that, here:</p>
  
  <pre><code>/* 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,&amp;tolua_err) ||
       !tolua_isnoobj(tolua_S,2,&amp;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'.",&amp;tolua_err);
   return 0;
  #endif
  }
  #endif //#ifndef TOLUA_DISABLE
  </code></pre>
  
  <p>And the error message THAT produces seems to confirm my theory: "error in function 'new'. argument #2 is 'userdata'; '[no object]' expected."
  i.e. it wasn't expecting/doesn't need me to pass in that lua_State pointer</p>
  
  <p>I'm at a loss, I have a lot of trouble finding solutions to problems with lua because tutorials/documentation seem to be pretty thin on the ground where tolua++ is concerned, but it's too late to change binding library now.</p>
  
  <p>Any help would be much appreciated, I hope I've provided enough to diagnose the problem.</p>
  
  <p><strong>EDIT:</strong> Here's my TestClass.cpp code (you can probably ignore method1, 2 and 3 as they don't seem to be called because of this error):</p>
  
  <pre><code>#include "TestClass.h"
  #include &lt;iostream&gt;
  
  TestClass::TestClass(lua_State *L)
  {
      num = NULL;
      lState = L;
  }
  
  int TestClass::method1()
  {
      int iStatus = luaL_loadfile( lState, "lua2.lua" );
      if (iStatus)
      {
          std::cout &lt;&lt; "Error: " &lt;&lt; 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 &lt;&lt; "Error: " &lt;&lt; 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 &lt;&lt; "Error: " &lt;&lt; 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 &lt;&lt; (char)num &lt;&lt; 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,&amp;tolua_err) ||
       !tolua_isnoobj(tolua_S,2,&amp;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'.",&amp;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,&amp;tolua_err) ||
       !tolua_isnoobj(tolua_S,2,&amp;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'.",&amp;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,&amp;tolua_err) ||
       !tolua_isnoobj(tolua_S,2,&amp;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-&gt;method1();
     tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
    }
   }
   return 1;
  #ifndef TOLUA_RELEASE
   tolua_lerror:
   tolua_error(tolua_S,"#ferror in function 'method1'.",&amp;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,&amp;tolua_err) ||
       !tolua_isnumber(tolua_S,2,0,&amp;tolua_err) ||
       !tolua_isnoobj(tolua_S,3,&amp;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-&gt;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'.",&amp;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,&amp;tolua_err) ||
     !tolua_isnoobj(tolua_S,2,&amp;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-&gt;method3();
    }
   }
   return 0;
  #ifndef TOLUA_RELEASE
   tolua_lerror:
   tolua_error(tolua_S,"#ferror in function 'method3'.",&amp;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) &amp;&amp; LUA_VERSION_NUM &gt;= 501
   TOLUA_API int luaopen_TestClass (lua_State* tolua_S) {
   return tolua_TestClass_open(tolua_S);
  };
  #endif
  </code></pre>