Closed SomebodyOdd closed 1 year ago
Hi @SomebodyOdd,
Well, that's interesting.
There seems to be a difference in the Windows and Linux versions of the C# compiler. Specifically, the platforms differ in the intrinsic delegate types associated with methods. On Windows you get a custom delegate that captures params
and default argument semantics. On Linux you just get Action
or Func
.
As a result, the following works on Windows but fails to compile on Linux:
public class Program {
public static void Main() {
var paramsMethod = ParamsMethod;
paramsMethod("123", "321", "231");
}
public static void ParamsMethod(params string[] args) => Array.ForEach(args, Console.WriteLine);
}
The compilation error on Linux is "error CS1593: Delegate 'Action<string[]>' does not take 3 arguments". Surprisingly, when built on Windows, the code runs on Linux without any problems.
Anyway, that's the root cause of the issue here. It seems to be a C# compiler bug, and we'll report it internally. In the meantime, you can work around it by specifying the delegate type explicitly. Here's a ClearScript sample that works on both platforms:
public class Program {
public delegate void ParamsDelegate(params string[] args);
public delegate void DefaultArgDelegate(string? arg = null);
public static void Main() {
using var engine = new V8ScriptEngine();
engine.AddHostObject("paramsMethod", new ParamsDelegate(ParamsMethod));
engine.Execute("paramsMethod('123', '321', '231')");
engine.AddHostObject("defaultArgMethod", new DefaultArgDelegate(DefaultArgMethod));
engine.Execute("defaultArgMethod()");
}
public static void ParamsMethod(params string[] args) => Array.ForEach(args, Console.WriteLine);
public static void DefaultArgMethod(string? arg = null) => Console.WriteLine(arg ?? "[null]");
}
Thanks, and good luck!
Workaround did the trick, thank you! Any issues on other Github repos I could follow about this? Or should I report this somewhere else?
Any issues on other Github repos I could follow about this?
We reported the issue here.
This appears to have been fixed in .NET 7.0.200.
Hello! I've found some code examples, that work on Windows but throw errors on Linux environments. This was caught during unit tests in our CI\CD environment and reproduces with dotnetfiddle. Didn't try to reproduce on Linux in my own VM yet, but I bet it will. Here are some code that illustrate this (it seems, that dotnetfiddle uses Linux runtime for .NET 7, because Environment.OSVersion returns Unix 5.15.0.1042). BOTH of those snippets run to completion on Windows without errors.
Calling a params method fails: https://dotnetfiddle.net/82teQe
Exception stacktrace
````` Unhandled exception. Microsoft.ClearScript.ScriptEngineException: Error: Invalid argument specified for parameter 'obj' ---> Microsoft.ClearScript.ScriptEngineException: Error: Invalid argument specified for parameter 'obj' ---> System.ArgumentException: Invalid argument specified for parameter 'obj' at Microsoft.ClearScript.Util.InvokeHelpers.GetCompatibleArg(String paramName, Type type, Object value) at Microsoft.ClearScript.Util.InvokeHelpers.GetCompatibleArg(ParameterInfo param, Object value) at Microsoft.ClearScript.Util.InvokeHelpers.InvokeMethodInternal[T](IHostContext context, T method, Object target, Object[] args, Func`4 invoker, Type returnType, ScriptMemberFlags flags) at Microsoft.ClearScript.Util.InvokeHelpers.InvokeMethod(IHostContext context, MethodInfo method, Object target, Object[] args, ScriptMemberFlags flags) at Microsoft.ClearScript.Util.InvokeHelpers.InvokeDelegate(IHostContext context, Delegate del, Object[] args) at Microsoft.ClearScript.Util.InvokeHelpers.TryInvokeObject(IHostContext context, Object target, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, Boolean tryDynamic, Object& result) at Microsoft.ClearScript.HostItem.InvokeHostMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, Boolean& isCacheable) at Microsoft.ClearScript.HostItem.InvokeMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean bypassTunneling, Boolean& isCacheable) at Microsoft.ClearScript.HostItem.<>c__DisplayClass147_0.Calling method without giving default params fails: https://dotnetfiddle.net/HFyH97
Exception stacktrace
````` Unhandled exception. Microsoft.ClearScript.ScriptEngineException: Error: Parameter count mismatch. ---> Microsoft.ClearScript.ScriptEngineException: Error: Parameter count mismatch. ---> System.Reflection.TargetParameterCountException: Parameter count mismatch. at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at Microsoft.ClearScript.Util.InvokeHelpers.<>c.ClearScript version: 7.4.3 Windows version: Win 10 Enterprise 22H2 Runtime version (Windows): 6.0.21 Runtime version (Dotnetfiddle): 7.0.5 (from System.Environment.Version) Runtime version (CI/CD): 6.0.20 (from System.Environment.Version)