views:

126

answers:

2

Hello world! I'm trying to integrate Lua to my C# app when I hit a little snag. I was hoping someone with more expertise could help point me to the right direction.

Let's say I have the following C# methods:

public void MyMethod(int foo) { ... }
public void MyMethod(int foo, int bar) { ... }

I would like to register it to my Lua script environment so that I can do something like this:

-- call method with one param
MyMethod(123)
-- call method with two params
MyMethod(123, 456)

I tried RegisterFunction("MyMethod", this, this.GetType().GetMethod("MyMethod")) but it reasonably complains about ambiguous match. Any ideas?

A: 

You could register the functions with different names and then use a pure Lua function to dispatch to the right method by checking the arguments

function MyMethod(foo, bar)
    if bar then
        MyMethod1(foo, bar)
    else
        MyMethod2(foo)
    end
end

Alternatively, you could implement this proxy function in C# and bind that instead directly binding each overloaded method.

Judge Maygarden
Thanks judge. I guess there's not a cleaner way to do it without proxy methods? Proxy methods feels like a hack :)
JeffreySadeli
It's not really a hack; that's just how variable arguments are handled in Lua. I suppose you could call any disparate language interface a hack. ;)
Judge Maygarden
+1  A: 

The ambiguous method exception is actually raised because of the call to GetMethod: when the argument to GetMethod is a string (method name) without specifying a Type[] for the parameters, and there is more than one method by that name, the exception is thrown.

If you don't have to strictly bind single methods like in your question, you can register the class as demonstrated in the LuaInterface test code:

    private Lua _Lua;

    public void Init()
    {
        _Lua = new Lua();

        GC.Collect();  // runs GC to expose unprotected delegates
    }

    public void TestMethodOverloads()
    {
        Init();

        _Lua.DoString("luanet.load_assembly('mscorlib')");
        _Lua.DoString("luanet.load_assembly('TestLua')");
        _Lua.DoString("TestClass=luanet.import_type('LuaInterface.Tests.TestClass')");
        _Lua.DoString("test=TestClass()");
        _Lua.DoString("test:MethodOverload()");
        _Lua.DoString("test:MethodOverload(test)");
        _Lua.DoString("test:MethodOverload(1,1,1)");
        _Lua.DoString("test:MethodOverload(2,2,i)\r\nprint(i)");
    }

This should correctly call your overloads.

Otherwise, you'll have to call the GetMethod overload that takes a Type[] argument and bind to separate Lua functions, or stick with @Judge's answer.

Mark Rushakoff
thanks mark, looks like i'll use judge's trick and yours to get this one working. thanks again for the help.
JeffreySadeli