How to use C# static string with Nlua - c#

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.

Related

Convert IsNumeric(textbox.Text) vb net code in c# [duplicate]

I know it's possible to check whether the value of a text box or variable is numeric using try/catch statements, but IsNumeric is so much simpler. One of my current projects requires recovering values from text boxes. Unfortunately, it is written in C#.
I understand that there's a way to enable the Visual Basic IsNumeric function in Visual C# by adding a reference to Visual Basic, though I don't know the syntax for it. What I need is a clear and concise walkthrough for enabling the IsNumeric function in C#. I don't plan on using any other functions indigenous to Visual Basic.
public bool IsNumeric(string value)
{
return value.All(char.IsNumber);
}
To totally steal from Bill answer you can make an extension method and use some syntactic sugar to help you out.
Create a class file, StringExtensions.cs
Content:
public static class StringExt
{
public static bool IsNumeric(this string text)
{
double test;
return double.TryParse(text, out test);
}
}
EDIT: This is for updated C# 7 syntax. Declaring out parameter in-line.
public static class StringExt
{
public static bool IsNumeric(this string text) => double.TryParse(text, out _);
}
Call method like such:
var text = "I am not a number";
text.IsNumeric() //<--- returns false
You could make a helper method. Something like:
public bool IsNumeric(string input) {
int test;
return int.TryParse(input, out test);
}
It is worth mentioning that one can check the characters in the string against Unicode categories - numbers, uppercase, lowercase, currencies and more. Here are two examples checking for numbers in a string using Linq:
var containsNumbers = s.Any(Char.IsNumber);
var isNumber = s.All(Char.IsNumber);
For clarity, the syntax above is a shorter version of:
var containsNumbers = s.Any(c=>Char.IsNumber(c));
var isNumber = s.All(c=>Char.IsNumber(c));
Link to unicode categories on MSDN:
UnicodeCategory Enumeration
Using C# 7 (.NET Framework 4.6.2) you can write an IsNumeric function as a one-liner:
public bool IsNumeric(string val) => int.TryParse(val, out int result);
Note that the function above will only work for integers (Int32). But you can implement corresponding functions for other numeric data types, like long, double, etc.
http://msdn.microsoft.com/en-us/library/wkze6zky.aspx
menu:
Project-->Add Reference
click: assemblies, framework
Put a checkmark on Microsoft.VisualBasic.
Hit OK.
That link is for Visual Studio 2013, you can use the "Other versions" dropdown for different versions of visual studio.
In all cases you need to add a reference to the .NET assembly "Microsoft.VisualBasic".
At the top of your c# file you neeed:
using Microsoft.VisualBasic;
Then you can look at writing the code.
The code would be something like:
private void btnOK_Click(object sender, EventArgs e)
{
if ( Information.IsNumeric(startingbudget) )
{
MessageBox.Show("This is a number.");
}
}
Try following code snippet.
double myVal = 0;
String myVar = "Not Numeric Type";
if (Double.TryParse(myVar , out myNum)) {
// it is a number
} else {
// it is not a number
}
I usually handle things like this with an extension method. Here is one way implemented in a console app:
namespace ConsoleApplication10
{
class Program
{
static void Main(string[] args)
{
CheckIfNumeric("A");
CheckIfNumeric("22");
CheckIfNumeric("Potato");
CheckIfNumeric("Q");
CheckIfNumeric("A&^*^");
Console.ReadLine();
}
private static void CheckIfNumeric(string input)
{
if (input.IsNumeric())
{
Console.WriteLine(input + " is numeric.");
}
else
{
Console.WriteLine(input + " is NOT numeric.");
}
}
}
public static class StringExtensions
{
public static bool IsNumeric(this string input)
{
return Regex.IsMatch(input, #"^\d+$");
}
}
}
Output:
A is NOT numeric.
22 is numeric.
Potato is NOT numeric.
Q is NOT numeric.
A&^*^ is NOT numeric.
Note, here are a few other ways to check for numbers using RegEx.
Tested with Net6 and universal with object because needed in my app:
public static bool IsNumeric(this object text) => double.TryParse(Convert.ToString(text), out _);
Works with null and string.empty and also tested "".
Is numeric can be achieved via many ways, but i use my way
public bool IsNumeric(string value)
{
bool isNumeric = true;
char[] digits = "0123456789".ToCharArray();
char[] letters = value.ToCharArray();
for (int k = 0; k < letters.Length; k++)
{
for (int i = 0; i < digits.Length; i++)
{
if (letters[k] != digits[i])
{
isNumeric = false;
break;
}
}
}
return isNumeric;
}

How do you convert a single Unicode code point to a string at runtime?

Let's say I have the following code point: u1F64A (which is the 🙊 emoji).
This can be written as:
string monkey = "\u1F64A";
How would I convert a known codepoint (as an integer) to a string at runtime though?
int codepoint = 0xF64A;
string monkey = //?
When I want to play with Emojis in C#, I build a helper class just like this:
public class Emoji
{
readonly int[] codes;
public Emoji(int[] codes)
{
this.codes = codes;
}
public Emoji(int code)
{
codes = new int[] { code };
}
public override string ToString()
{
if (codes == null)
return string.Empty;
var sb = new StringBuilder(codes.Length);
foreach (var code in codes)
sb.Append(Char.ConvertFromUtf32(code));
return sb.ToString();
}
}
This way, I can just do string monkeyEmoji = new Emoji(0xF64A);
It also supports emojis with multiple code points (yes, those exist and are a pain)
Is the above code even compilable? It doesn't compile on my machine.
And why should it, \u1F64A is not a valid string.
I think what could work is string monkey = $"{char.ConvertToUtf32((char) 0xF64, 'A')}", but that is just a guess. I just answered to clarify that the first line of code you wrote is not compilable on my machine.

How to get value of escape characters in c#?

I want to know the ASCII value of an escape sequence in runtime. for example:
string x = "\\b";
char res = someFunctionCall(x);
//res = '\b' = 0x08
The difference here that I only know x at runtime.
I know that this can be made with simple switch (already doing that), but I was wondering if it can be made using some existing c# call. I tried Char.Parse(x), but it didn't work.
Edit: I'm not talking here about converting '\b' to its corresponding ASCII value, rather, I'd like to parse "\\b" as what you write in c# to get '\b'.
There is slow but rather easy way to do this. compile your code at runtime and let c# compiler take care of that! I know its overkill for what you want. but it works.
Anyway as #JonSkeet noted you can use a dictionary for simple escape sequences. take your list from here https://msdn.microsoft.com/en-us/library/h21280bw.aspx
Here is solution by compiling code at runtime, Note that its VERY SLOW, so I suggest you to replace and map multiple characters at once so compiler only runs and evaluate all of that for you only once.
using System;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
//...
private static void Main()
{
string x = "\\b";
string res = Evaluate(x);
Console.WriteLine(res);
}
public static string Evaluate(string input)
{
// code to compile.
const string format = "namespace EscapeSequenceMapper {{public class Program{{public static string Main(){{ return \"{0}\";}}}}}}";
// compile code.
var cr = new CSharpCodeProvider().CompileAssemblyFromSource(
new CompilerParameters { GenerateInMemory = true }, string.Format(format, input));
if (cr.Errors.HasErrors) return null;
// get main method and invoke.
var method = cr.CompiledAssembly.GetType("EscapeSequenceMapper.Program").GetMethod("Main");
return (string)method.Invoke(null, null);
}

how to convert a string to a ushort

I have researched all of the questions that match my query and tried their solutions however none appear to work for me so I am asking how I convert a string to a ushort I have this set up all ready
public static string vid
{
get { return "<vehicleid>"; }
}
I've tried to use this : short[] result = vid.Select(c => (ushort)c).ToArray();
but when I go to put the vid ushort into this bit
[RocketCommand("vehicle", "This command spawns you a vehicle!", "<vehicleid>", AllowedCaller.Player)]
public void ExecuteCommandVehicle(IRocketPlayer caller, string[] command)
{
UnturnedPlayer spawner = (UnturnedPlayer)caller;
spawner.GiveVehicle(vid);
}
I get the following error :
Severity Code Description Project File Line Suppression State
Error CS1503 Argument 1: cannot convert from 'string' to 'ushort' arena v by FridgeBlaster C:\Users\Jonathan\Documents\Visual Studio 2015\Projects\arena v by FridgeBlaster\arena v by FridgeBlaster\vehicle.cs 71 Active
What you're looking for is ushort.TryParse or ushort.Parse methods.
I would suggest using this piece of code :
ushort[] result = vid.Where(i => ushort.TryParse(i, out short s)).Select(ushort.Parse);
Or if you do not use latest C# version :
ushort[] result = vid.Where(i => { ushort r = 0; return ushort.TryParse(i, out r); }).Select(ushort.Parse);
Okay so the problem ( as what your error says ) is that your GiveVehicle method accepts ushort as an argument and you're putting string type in it. Try doing something like this :
ushort val = 0;
if(ushort.TryParse(vid, out val))
{
UnturnedPlayer spawner = (UnturnedPlayer)caller;
spawner.GiveVehicle(val);
}
Based on this source which is responsible for calling method marked with RocketCommand attribute. Your <"vehicleid"> is/should be stored in a command array on first place. So to get this out and convert use something like this :
if(command.Length > 0)
{
ushort val = 0;
if(!string.IsNullOrWhiteSpace(command[0]) && ushort.TryParse(command[0], out val))
{
UnturnedPlayer spawner = (UnturnedPlayer)caller;
spawner.GiveVehicle(val);
}
}
For a simple string to ushort conversion: UInt16.Parse(string)
Based on the line short[] result = vid.Select(c => (ushort)c).ToArray(); it looks like there might be multiple IDs in a single string (each character, I assume).
If that's the case, try something like this:
ushort[] result = vid.ToCharArray().Select(c => (ushort) c).ToArray();
If you've got several actual numbers in the string separated by a character (e.g. "13,15,18"), give this a shot:
ushort[] result = vid.Split(separator).Select(str => ushort.Parse(str)).ToArray();
For either of these options, make sure you include using directives for the System and System.Linq namespaces.
With discussion on this and other answers, it looks like command is the result of tokenizing "/vehicle <id>". In this case, the body of the ExecuteCommandVehicle(IRocketPlayer, string[]) method should be similar to this:
ushort result = 0;
if (ushort.TryParse(command[1], out result)) {
UnturnedPlayer spawner = caller as UnturnedPlayer;
caller?.GiveVehicle(result);
}
Either you want to convert the string to a short:
Int16.Parse(...)
or
Int16.TryParse(...)
or you want to convert char to short by first converting string to array of chars:
vid.ToCharArray[..]

VB.Net / C# Spintax help?

Can anyone give me an example of spintax snippet for C# / VB.NET programming language. If you don't know what that is (the spintax), well basically it is a way of putting different values of strings and then randomly choosing one. For instance:
{Hello|Hi|Greetings} my name is {Tom|John|Eaven} and I like {turtles|programming|ping pong}.
And it would choose between { } splitting those strings inside of the {} string with delimiter of | so it randomly outputs the final string.
Here is a class for C# which handles that snippet:
public class Spinner
{
private static Random rnd = new Random();
public static string Spin(string str)
{
string regex = #"\{(.*?)\}";
return Regex.Replace(str, regex, new MatchEvaluator(WordScrambler));
}
public static string WordScrambler(Match match)
{
string[] items = match.Value.Substring(1, match.Value.Length - 2).Split('|');
return items[rnd.Next(items.Length)];
}
}
And try it:
Console.WriteLine(Spinner.Spin("{Hello|Greetings|Merhaba} World, My name is {Beaver|Michael} Obama"));
Here is the complete article: http://jeremy.infinicastonline.com/2010/11/spintax-class-for-c-net/

Categories

Resources