How do you pass an object from c# to lua's function?

1.5k views Asked by At

I'm using Lua interface on c# to pass an object I created to lua's function. It successfully calls the function, but lua is keep throwing an error:

LuaInterface.LuaException: /hook.lua:32: attempt to index local 'objj' (a nil value)

This is the c# code:

public class PerObj
{
    public string name;
    public PerObj() 
    {
    }
}

PerObj obj = new PerObj();
LuaFunction lf = lua.GetFunction ("item.HookMe");
lf.Call(obj);

And here's the lua code:

function item:HookMe(objj)
    objj.name= "lalala"
end

The function is actually being called, but I'm not sure it's not working...

2

There are 2 answers

9
IS4 On BEST ANSWER

Change the function definition to:

function item.HookMe(objj)
    objj.name= "lalala"
end

The colon in the original definition means that the function has also the self parameter. Those function are called like this: object:HookMe(). But you want to call it directly, so the colon is not applicable.

Edit:
If you want to keep the function defininition and retain self, call it like this:

lf.Call(null, obj);

To call it passing also the self object:

lf.Call(lua["item"], obj);
0
Tom Blodget On

It seems like the problem is the design of the Lua method (but it really depends on the intent):

Instead of

function item:HookMe(objj)
    -- self not used
    objj.name= "lalala"
end

This would work better in the given example:

function item:HookMe()
    self.name= "lalala"
end

The reason (as well discussed in other answers) is that declaring a function with the method syntax (:) adds an implied first formal parameter self. The caller can pass anything as the first actual argument but the contract is usually to pass the parent table of the function so it can access its sibling fields.

In this case, name seems to be a sibling of HookMe so the method shouldn't be operating on an arbitrary table passed as objj but instead on self.