1

I am using NLua for script interface with my application. I want to send keyboard input from LUA language to my C# code.

I do with this C# code.

   using (Lua lua = new Lua())
   {
      lua.LoadCLRPackage();

      lua.RegisterFunction("keypressC", null, typeof(TestNLUA).GetMethod("keypressC"));
      lua.RegisterFunction("keypressS", null, typeof(TestNLUA).GetMethod("keypressS"));

      lua["Key"] = new SpecialKey();
   }

    public class SpecialKey
    {
        public static readonly char EnterC = '\uE007'; 
        public static readonly string EnterS = Convert.ToString(EnterC);
    }

   public class TestNLUA
   {
      public static void keypressC(char key)
      {
         // key = 57351 => OK
      }

      public static void keypressS(string key)
      {
         char[] akey = key.ToCharArray();
         // akey[0] = 63 = ? (question mark) => KO
      }
   }

And in LUA Script I do

keypressC(Key.EnterC)
keypressS(Key.EnterS)

In keypressC, Nlua passe value 57351 to key parameter. It's OK.

In keypressS, Nlua passe value "?" to key parameter. It's KO. I have no idea why there is the character "?". Looks like a marshaling error in NLua (i.e. LuaInterface)?

Can you help me?

P̲̳x͓L̳
  • 3,615
  • 3
  • 29
  • 37
LeMoussel
  • 5,290
  • 12
  • 69
  • 122

1 Answers1

1

This is a marshaling problem in nLua/LuaInterface.

It uses Marshal.StringToHGlobalAnsi to marshal a string from C# to Lua.
It uses Marshal.PtrToStringAnsi to marshal a string from Lua to C#.

If you round-trip your example string through these functions, you can see it reproduces your problem:

 string test = "\uE007";

 Console.WriteLine(test);
 Console.WriteLine("{0}: {1}", test[0], (int) test[0]);

 IntPtr ptr = Marshal.StringToHGlobalAnsi(test);
 string roundTripped = Marshal.PtrToStringAnsi(ptr, test.Length);

 Console.WriteLine(roundTripped);
 Console.WriteLine("{0}: {1}", roundTripped[0], (int) roundTripped[0]);

Output:

?
?: 57351
?
?: 63

Your problem goes away if you change the the marshaling functions to use Uni instead of Ansi, but you'd need to build nLua/LuaInterface from source.

Mud
  • 28,277
  • 11
  • 59
  • 92
  • Because of this marshaling problem in nLua/LuaInterface, I test **[NeoLua](https://neolua.codeplex.com/)**, Lua for .net dynamic language runtime. In effect **NeoLua** uses the .NET string, and you can use all the functionality e.g. `' test ':Trim()` – LeMoussel Mar 27 '14 at 17:49
  • I tried NeoLua, but it was too buggy. For instance, even the ["simple example" on their documentation page](http://neolua.codeplex.com/documentation) crashes. – Mud Mar 27 '14 at 18:04
  • I didn't have problems. Opens a discussion on [codeplex](https://neolua.codeplex.com/discussions), NeoLithos responds quickly. – LeMoussel Mar 28 '14 at 16:57
  • 1
    Fixed in NLua, will be in NuGet soon https://github.com/NLua/NLua/commit/1523aa966f1de118f34ab99a935abb463c537705 – Vinicius Jarina Apr 07 '14 at 19:35