Question

I have discovered the cause of the issue. An answer has been posted below.


EDIT: The problem has changed, please see "The problem" section.

I am using LuaInterface. The generic call for lua functions using this library has this signature LuaFunction.Call(params object[] args). I have created a wrapper function that catches exceptions from the library and formats them for display on the in-game console window.

I am trying to call a lua function, but it is not receiving the arguments. This is the line in C#

Game.Instance.scriptEngine.Call("GenerateChunk", chunks[chunkID], GetChunkGridPosition(chunkID));

Which is simply wrapping a call to this Lua function that accepts two arguments:

//lua
function GenerateChunk(worldChunk, chunkGridPosition)
    Log(LogLevel.Error, worldChunk.ToString());
    Log(LogLevel.Error, chunkGridPosition.ToString());
end

that merely calls back into a C# Log function (which resolves correctly, and is visible in the Lua context).

The problem is that I am getting an "invalid arguments to method call" error from luainterface when attempting to call the GenerateChunk function, throwing this back:


invalid arguments to method call
   at JASG.ScriptEngine.LuaError(Exception ex) Scripting\ScriptEngine.cs:line 144
   at JASG.ScriptEngine.Call(String fnName, Object[] args) Scripting\ScriptEngine.cs:line 86
   at JASG.ChunkManager.WakeChunk(Int32 chunkID) World\ChunkManager.cs:line 123
   at JASG.ChunkManager.GetChunk(Int32 chunkID, Boolean wakeIfAsleep) World\ChunkManager.cs:line 53

I have tried various ways of calling the ScriptEngine.Call method, tried wrapping the arguments in an object[] array, etc., but no dice. Any ideas why lua is not receiving my arguments that I am passing? I have verified both arguments are non-null in C# when being passed in.

Was it helpful?

Solution 3

I incorrectly identified the problem as being with the call into Lua. The error message I was receiving was in fact originating from the Lua script calling back into my C# Log function.

I have discovered the hard way that in spite of exposing the enum LogManager.LogLevel to the lua script envronment, Lua does not support enum types. Thus,

Log(LogLevel.Debug, "hello"); 

was becoming

Log("Debug", "hello");

when marshalled by LuaInterface for the C# function. It was not until I created an ancillary ScriptLog(string level, string msg) that I was able to properly use the function from within lua. I wanted to keep the functionality of being able to use the enum names within Lua.

NOTE: As Lua does not support enum types, tonumber(LogLevel.Debug) fails as well.

OTHER TIPS

I've never used Lua before, but I've seen this kind of strange behaviors with calling COM objects (or any interop), or when the target assembly call is loaded on a different App Domain, or any other technology that intercommunicates a .Net assembly with a non-.Net one.

Have you tried using the [Serializable] attribute on the classes that define the result of "chunks[chunkID]" and "GetChunkGridPosition(chunkID)"? Are all your interop classes and types compatible between both assemblies?

Just thinking out loud here.

Side note: you should reduce your code to the shortest example that produces the problem. For instance, we don't need to see your wrapper function. You should have tried removing it. If that solved the problem, it's an important clue you should have been mentioned. If the problem remained, then that code is just a distracting irrelevancy for anyone reading this.

Your problem could be in your Log function. Everything thing else looks fine, that's the only code we can't actually see, and your problem can be reproduced like this:

public static void Log(int errorLevel, string message)
{
    Console.WriteLine(message);
}

public void Test()
{
    var lua = new Lua();
    lua.RegisterFunction("Log", this, GetType().GetMethod("Log"));
    lua.DoString("function foo() Log('a','b') end");
    lua.GetFunction("foo").Call();
}

In this case, because 'a' cannot be marshaled into a number.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top