[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:00:02 -0700
I was afraid that the answer would be somewhat complex. All of this
just to wrap up 3 classes, though they are classes from hell with many
methods and properties. Guess it may be time to find one of those
ScriptingLanguageX-->Delphi Code Wrapper generators and modify it to
fix the LUA Library :). Since I've hit this once I know I'll need it
again :)
- 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.