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?
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.