GameCTO / luainterface

Automatically exported from code.google.com/p/luainterface
0 stars 0 forks source link

Cannot call C# methods with params object[] argument #18

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
Run the example provided in linkpad or make a console program and test it 
(replace the .Dump() with Console.write if not using Linqpad)

What is the expected output? 
1-2-3
1-2-3

What do you see instead?
1-2-3
LuaException (invalid arguments to method: Join:run

Apperently it cannot call C# methods that have params object[] arguments.

I have tried to use a Lua array as argument, surrounding the 1,2,3 with {} and 
also introducing a variable p = {1,2,3} and pasing that to the method, same 
result.

Is this possible or am I doing it all wrong, tried to find a forum to query but 
found none that have been active the last year.

What version of the product are you using? On what operating system?
LuaInterface: 2.0.0.16708
Lua51.dll
Windows XP3

Please provide any additional information below.

Example program written for Linqpad

void Main()
{
    LuaInterface.Lua e = new LuaInterface.Lua();
    Join j = new Join();
    e["Join"] = j;
    e.DoString("function test() return Join:run(1,2,3) end");
    LuaInterface.LuaFunction f = e.GetFunction("test");
    j.run(1,2,3).Dump();
    f.Call().Dump();
}

// Define other methods and classes here

public class Join {
    public string run(params object[] args) {
        return string.Join("-", args);
    }
}

Original issue reported on code.google.com by dmartens...@gmail.com on 2 Jul 2010 at 8:19

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Hi!

I believe the problem you are having is that when you create an object using 
{}, LuaInterface converts it to a LuaTable object when passing it through, 
rather than an object array -- you can see this by doing something like 
e.DoString("return {1,2,3};")[0].Dump();  I believe the best way to get the 
desired functionality is to manually create an object array using the import 
type functionality.  I've attached a text file that has an example I created 
based off of your original LinqPad script.  It worked using both the 2.0.1 
download and the latest trunk version.

However, while this method works, it might be interesting to look into making 
the function call logic a tiny bit smarter when it comes to params arguments.  
I'm marking this as an enhancement to look into for now (unless you find the 
script I provided doesn't work, at which point we can switch it back and look 
into your issue further).

Original comment by eonstorm@gmail.com on 2 Jul 2010 at 11:23

Attachments:

GoogleCodeExporter commented 9 years ago
Based on your information I made a cleaner solution (from the script 
perspective) that will require less coding for each script (they will change 
more often than the C# source)

I added an extension class

class LuaExtensions {
    public object[] Table2Array(LuaInterface.LuaTable table) {
        List<object> l = new List<object>();
        foreach (DictionaryEntry e in table)
        {
            l.Add(e.Value);
        }
        return l.ToArray();
    }
}

and registered the function

    LuaExtensions le = new LuaExtensions();
    e.RegisterFunction("params", le, le.GetType().GetMethod("Table2Array"));

And managed to call the method like this

    e.DoString("function test() return Join:run(params({1,2,3})) end");

This was just for the example of cause, in the real implementation I will wrap 
it all in a nice package but this works for me now, thanks very much for the 
help  :)

Full source of the modified example that works:

void Main()
{
    LuaInterface.Lua e = new LuaInterface.Lua();
    Join j = new Join();
    LuaExtensions le = new LuaExtensions();
    e.RegisterFunction("params", le, le.GetType().GetMethod("Table2Array"));
    e["Join"] = j;
    e.DoString("function test() return Join:run(params({1,2,3})) end");
    LuaInterface.LuaFunction f = e.GetFunction("test");
    j.run(1,2,3).Dump();
    f.Call()[0].Dump();
}

public class Join {
    public string run(params object[] args) {
        return string.Join("-", args);
    }
}

class LuaExtensions {
    public object[] Table2Array(LuaInterface.LuaTable table) {
        List<object> l = new List<object>();
        foreach (DictionaryEntry e in table)
        {
            l.Add(e.Value);
        }
        return l.ToArray();
    }
}

When I'm at it, does LuaInterface support extension methods or is that also a 
future feature ;)

Original comment by dmartens...@gmail.com on 2 Jul 2010 at 12:05

GoogleCodeExporter commented 9 years ago
I do not believe it does currently.  It is certainly something that could be 
worth looking into though.  I will create another enhancement issue to look 
into it.

Original comment by eonstorm@gmail.com on 2 Jul 2010 at 1:34

GoogleCodeExporter commented 9 years ago
I am closing this as a WontFix issue since the current code supports the 
desired functionality, albeit in a different way.

Original comment by eonstorm@gmail.com on 2 Jul 2010 at 1:37

GoogleCodeExporter commented 9 years ago
Hey, just to let you know - I went ahead and looked into making the method 
calling logic smarter in regards to params arguments.  I put it in as an issue 
(issue 22) and implemented the necessary changes tonight.  It should work very 
closely to what you originally tried as of revision 17.

Original comment by eonstorm@gmail.com on 3 Jul 2010 at 4:16