lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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.