[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: RE: Problems with LUA 5.02 and user objects
- From: jdarling@...
- Date: Mon, 03 Apr 2006 14:01:30 -0700
Sorry for duplicate messages on the same topic, but by chance do you
still have some sample Delphi code lying around of how you wrapped up
objects? This has been a real pain in my side for about a week now,
and the best I've got working is a full API that is then wrapped up on
the LUA side by creating object wrappers. Not eligant at all and easy
to break :(
- Jeremy
"Help I suffer from the oxymoron Corporate Security."
> -------- Original Message --------
> Subject: Re: Problems with LUA 5.02 and user objects
> From: Romulo Bahiense <romulo@icontroller.com.br>
> Date: Mon, April 03, 2006 2:45 pm
> To: Lua list <lua@bazar2.conectiva.com.br>
>
> Hi,
>
> I think the problem is here:
>
> > if Assigned(m.Code) then
> > result := TLuaObjectMethod(m)(l)
> > else
> > result := 0;
>
>
> You are calling the method in the instIndex function, returning it's
> result. Lua expects you to return that function instead.
>
> Suppose you have a class TFoo and a method bar(). When you instantiate a
> Lua userdata for the TFoo class, and write something like this:
>
> -- I don't know how your constructors looks like...
> local foo = TFoo.Create()
> foo:bar()
>
> foo's __index metamethod should return a function to be executed by the
> Lua VM and not on the "C side" (Delphi side ;).
>
> Basically you would have to replace those lines with:
>
> if Assigned(m.Code) then
> begin
> lua_pushcfunction(TLuaObjectMethod(m));
> Result:= 1;
> end
> else
> Result := 0;
>
> But a problem arises here, because a method is different from a Lua C
> Function. A method is a function that requires an implicit "Self"
> reference as the first argument and n other arguments as the
> function/procedure parameters, while a Lua C Function is a function that
> accepts only a pointer to a lua_State structure (record) and returns an
> integer (also, it has to be cdecl'ed). I think the best solution would
> be to create a generic LuaCFunction which would have as it's first two
> upvalues the parts of a TMethod record:
>
> function dummycclosure(L: PLuaState): integer; cdecl;
> var
> m: TMethod;
> begin
> m.Data:= lua_touserdata(L, lua_upvalueindex(1));
> m.Code:= lua_touserdata(L, lua_upvalueindex(2));
> Result:= TLuaObjectMethod(m)(L);
> end;
>
> And your instIndex would be:
>
> if Assigned(m.Code) then
> begin
> lua_pushlightuserdata(L, m.Data);
> lua_pushlightuserdata(L, m.Code);
> lua_pushcclosure(dummycclosure, 2);
> Result:= 1;
> end
> else
> Result := 0;
>
> This solution should work fine, but it creates a C closure each time it
> is called.
>
> There are other solutions for you problem, as creating binding functions
> for your class methods and then putting them into a table, perhaps
> replacing the __index function with that table, and settings it's
> __index metamethod for that __index function (confusing?).
>
> I have tried to create a binding mechanism sometime ago but I had to
> abandon it (cost x benefit). Most of the time, it is easier to create
> the binding functions manually than to create a run-time system[1]
> generic enough to accommodate both Delphi's and Lua's particularities. I
> wish you to be more lucky than me :)
>
> --rb
>
> 1. I tried to implement a run-time system to take advantage of Delphi's
> RTTI. I think that an offline engine would be a bit simpler to implement.
>
> ps: I have not tested any of the code I wrote.