如何使用C#静态字符串与Nlua

我正在使用NLua作为应用程序的脚本界面。我想将LUA语言中的键盘输入发送到我的C#代码中。

我用以下C#代码完成此操作。

   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 => 所以 far so good
      }

      public static void keypressS(string key)
      {
         char[] akey = key.ToCharArray();
         // akey[0] = 63 = ? (问号character) => 不好
      }
   }

而在LUA脚本中,我这样做:

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

在keypressC中,Nlua将值57351传递给键参数。没问题。

在keypressS中,Nlua将 "?" 值传递给键参数。这不好。我不知道为什么会有 "?" 字符。看起来像是NLua(即LuaInterface)中的封送错误?

你能帮我吗?

点赞
用户501459
用户501459

这是 nLua/LuaInterface 中的 marshaling 问题。

它使用 Marshal.StringToHGlobalAnsi 将 C# 中的字符串转换为 Lua 格式。

它使用 Marshal.PtrToStringAnsi 将 Lua 中的字符串转换为 C# 格式。

如果对示例字符串使用这些函数进行 round-trip,则会发现它会复现你的问题:

 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]);

输出结果:

?
?: 57351
?
?: 63

如果将 marshaling 函数从 Ansi 改为 Uni,则问题便会消失,但你需要从源代码构建 nLua/LuaInterface。

2014-03-26 20:16:54