Problems with creating a table from backend

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Problems with creating a table from backend

jdarling
I can't believe I can't find a sample of this, but I'm having problems
creating a table that contains "settings" for a method.  Below is the
code I've tried along with comments and the exception that comes back:

procedure PushParam(L : Plua_State; PropName, PropType, PropOption:
String);
var
  ptbl : Integer;
begin
  lua_newtable(L);
  ptbl := lua_gettop(L);// get the tables index
  lua_pushstring(L, 'Name');
  lua_pushstring(L, PChar(PropName));
  lua_settable(L, ptbl); // set the name/value pair to the new table
  lua_pushstring(L, 'Type');
  lua_pushstring(L, PChar(PropType));
  lua_settable(L, ptbl); // set the name/value pair to the new table
  lua_pushstring(L, 'Option');
  lua_pushstring(L, PChar(PropOption));
  lua_settable(L, ptbl); // set the name/value pair to the new table
end;

procedure PushMethodParams(L : Plua_State);
var
  tbl : Integer;
  m : PMethodInfo;
  i : Integer;
  po: String;
begin
  lua_pushstring(L, 'Params');
  lua_newtable(L);
  tbl := lua_gettop(L);// get the table reference
  lua_settable(L, LUA_GLOBALSINDEX);//set the var name "Params" = table
instance
  m := GetActiveMethodList;
  for i := 0 to Length(m.Params)-1 do
    begin
      case m.Params[i].ParamOp of
        ptVar : po := 'Var';
        ptConst : po := 'Const';
        ptOut : po := 'Out';
      else
        po := '';
      end;
      lua_pushnumber(L, i+1);// set the table index
      PushParam(L, m.Params[i].ParamName, m.Params[i].ParamType, po);
      lua_settable(L, tbl);
    end;
end;

Calling this and watching it shows that all the values are correct.  But
when I then do an execute and try to use Params as a table I get back
the error of:
[string ""]:2: attempt to index field `?` (a nil value)(2)

Any ideas of what I'm doing wrong, as I know its something.

Thanks,
 - Jeremy

"Help I suffer from the oxymoron Corporate Security."


Reply | Threaded
Open this post in threaded view
|

Re: Problems with creating a table from backend

Matt Campbell-2
Hello Jeremy:

The problem is that in the second procedure, you create the table,
retrieve its stack index, and then call lua_settable to make it a global
variable.  Calling lua_settable pops the newly created table from the
stack, making your stored stack index invalid.  Instead, that function
should begin as follows:

  lua_newtable(L);
  tbl := lua_gettop(L);// get the table reference
  lua_pushstring(L, 'Params');
  lua_pushvalue(L, tbl); // push it again to make it a global
  lua_settable(L, LUA_GLOBALSINDEX);//set the var name "Params" = table
instance

To keep your pushes and pops balanced, the function should now have this
at the end:

  lua_remove(L, tbl);

I hope this helps.

BTW, is this Delphi, or some other form of Pascal?  I don't really know
Pascal, but the relevant code was similar enough to C that I could
follow it.

--
Matt Campbell
Lead Programmer
Serotek Corporation
www.freedombox.info
"The Accessibility Anywhere People"

Reply | Threaded
Open this post in threaded view
|

RE: Problems with creating a table from backend

jdarling
In reply to this post by jdarling
Its actually generic Pascal.  I am using Delphi to test in as it still
works a bit better then Lazarus in my openion, but I can also compile
it in Pascal.

Just to make a sanity check then (I'll leave out all specific code) it
should look something like this then:

lua_newtable(L);
tbl = lua_gettop(L);
lua_pushstring(L, 'Params');
lua_pushvalue(L, tbl);
lua_settable(L, LUA_GLOBALSINDEX);
lua_pushnumber(L, 1);
lua_pushstring(L, 'Value 1');
lua_settable(L, tbl);
lua_pushnumber(L, 2);
lua_pushstring(L, 'Value 2');
lua_settable(L, tbl);
lua_remove(L, tbl);

then in my lua:
function Test(v, k)
  print(v..' '..k.."\n")
end
table.foreach(Params, Test)

In theory my output should be:
1 Value 1
2 Value 2

If so then this blows up in my face as well.  No warnings or errors, the
app just closes and dies.  I can read/write C/C++ as well, if you happen
to have some sample code of embedding a table in a table that would be
excelent :)

 - Jeremy

"Help I suffer from the oxymoron Corporate Security."


> -------- Original Message --------
> Subject: Re: Problems with creating a table from backend
> From: Matt Campbell <[hidden email]>
> Date: Thu, April 13, 2006 11:08 am
> To: Lua list <[hidden email]>
>
> Hello Jeremy:
>
> The problem is that in the second procedure, you create the table,
> retrieve its stack index, and then call lua_settable to make it a global
> variable.  Calling lua_settable pops the newly created table from the
> stack, making your stored stack index invalid.  Instead, that function
> should begin as follows:
>
>   lua_newtable(L);
>   tbl := lua_gettop(L);// get the table reference
>   lua_pushstring(L, 'Params');
>   lua_pushvalue(L, tbl); // push it again to make it a global
>   lua_settable(L, LUA_GLOBALSINDEX);//set the var name "Params" = table
> instance
>
> To keep your pushes and pops balanced, the function should now have this
> at the end:
>
>   lua_remove(L, tbl);
>
> I hope this helps.
>
> BTW, is this Delphi, or some other form of Pascal?  I don't really know
> Pascal, but the relevant code was similar enough to C that I could
> follow it.
>
> --
> Matt Campbell
> Lead Programmer
> Serotek Corporation
> www.freedombox.info
> "The Accessibility Anywhere People"

Reply | Threaded
Open this post in threaded view
|

Re: Problems with creating a table from backend

Matt Campbell-2
Is the second procedure from your original message supposed to leave the
table that it creates on the Lua stack?  If so, then take out the
lua_remove() function call that I gave you.

--
Matt Campbell
Lead Programmer
Serotek Corporation
www.freedombox.info
"The Accessibility Anywhere People"

Reply | Threaded
Open this post in threaded view
|

RE: Problems with creating a table from backend

jdarling
In reply to this post by jdarling
Hmm.... Oddly this still returns the same exception.  I'm using Lua
5.0.2 if that makes any difference.

Source in Delphi or C/C++:
  lua_newtable(L); // Create the table
  tbl = lua_gettop(L); // get the reference
  lua_pushstring(L, 'Params'); // place the table name on the stack
  lua_pushvalue(L, tbl); // place the table reference on the stack
  lua_settable(L, LUA_GLOBALSINDEX); // link them and make the
environment aware of them
  lua_pushnumber(L, 1); // push index on the stack
  lua_pushstring(L, 'Value 1'); // push value on the stack
  lua_settable(L, tbl); // link to our table
  lua_pushnumber(L, 2);  // push another index on the stack
  lua_pushstring(L, 'Value 2'); // push another value for the index
  lua_settable(L, tbl); // link to table

then in my lua script:
  function Test(v, k) -- prototype method
    print(v..' '..k.."\n") -- I know I could use print directly, but my
actual method does more
  end
  table.foreach(Params, Test) -- run test for each name/value pair in
table

In theory my output should be:
  1 Value 1
  2 Value 2

 - Jeremy

"Help I suffer from the oxymoron Corporate Security."


> -------- Original Message --------
> Subject: Re: Problems with creating a table from backend
> From: Matt Campbell <[hidden email]>
> Date: Thu, April 13, 2006 12:36 pm
> To: Lua list <[hidden email]>
>
> Is the second procedure from your original message supposed to leave the
> table that it creates on the Lua stack?  If so, then take out the
> lua_remove() function call that I gave you.
>
> --
> Matt Campbell
> Lead Programmer
> Serotek Corporation
> www.freedombox.info
> "The Accessibility Anywhere People"