I have this Js functions :
function Add (a, b)
{ return a+b;}
function Substract (a, b)
{ return a-b;}
I know (heard) that I can activate those functions on c# code using the dynamic keyword.
Can I get a help ( or beginning of help) to the solution by simple sample ?
edit
If I have a webBrowser ( winform) - which can help me. ( sorry to add this now).
You need a javascript interpreter if you want to execute javascript code. The C#s dynamic keyword is pretty useless in this aspect. You may take a look at Javascript .NET or Jint if you are trying to execute those functions in .NET code.
Here's an example with Jint:
using System;
using Jint;
class Program
{
static void Main()
{
var script = #"
function Add(a, b) {
return a + b;
}
function Substract(a, b) {
return a - b;
}
return Add(a, b);
";
var result = new JintEngine()
.SetParameter("a", 3)
.SetParameter("b", 5)
.Run(script);
Console.WriteLine("result: {0}", result);
}
}
Remark: what you have is not valid javascript. The var keyword cannot be used before function parameters. So you probably should start by fixing your code.
Related
I am trying to create a C# program that lets user's provide an implementation for for a function by inputting text into a text box. I provide the function header (input types, output type), they just need to provide actual implementation. I then store that function to call later. They might need to import something from the .NET framework, but nothing outside of it.
I don't care about security, this is just for a tool for internal use.
Is there an easy way to do this in .NET?
The usage would look something like (need to implement the CompileUserFunction function, which takes in an int and returns an object):
Func<int, object> CreateUserFunction(string input) {
Func<int, object> userFunc = CompileUserFunction(input);
return (i) => userFunc(i);
}
public void DoSomething() {
List<Func<int, object>> userFuncs = new List<Func<int, object>>();
string userInput = #"DateTime t = DateTime.Now;
t.AddDays(i);
return t;";
userFuncs.Add(CreateUserFunction(userInput));
userFuncs.Add(CreateUserFunction("return i;"));
userFuncs.Add(CreateUserFunction("i = i * 5; return i;"));
var result = userFuncs[0](5);
}
You can use code generation libs for that task.
I advice you to use Roslyn scripting API. I have done a similar task - parsing a string into delegate with it. The following example is taken from this link: https://blogs.msdn.microsoft.com/csharpfaq/2011/12/02/introduction-to-the-roslyn-scripting-api/
You will find there more examples
using Roslyn.Scripting.CSharp;
namespace RoslynScriptingDemo
{
class Program
{
static void Main(string[] args)
{
var engine = new ScriptEngine();
engine.Execute(#"System.Console.WriteLine(""Hello Roslyn"");");
}
}
}
There are other code generation tools and libs:
CodeDom - an old .Net code generation Framework. Probably can be used here but is more tricky.
https://learn.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/using-the-codedom
There were some libraries which were used to convert strings to Linq Expression trees, but it all seems to be outdated now.
There is also a possibility to create a Dynamic Method via Reflection.Emit but it is very low level - you need to define method implementation in IL instructions.
I want to call a python function from C# code. To do that, I used Python for .NET to call function as shown in the following lines of code
using System;
using Python.Runtime;
public class Test{
public static void Main(){
using(Py.GIL()){
dynamic lb = Py.Import("lb");
dynamic result = lb.analyze("SomeValue");
Console.WriteLine(result);
}
}
}
The python function is something like this:
def analyze(source, printout = False, raw = True):
# removed for bravity
So the question is, how can I set "raw" to False when I call the analyze function from C# code. I tried the following but it didn't work.
1. dynamic result = lb.analyze("SomeSource", raw : false); // No result
2. dynamic result = lb.analyze("SomeSource", #"raw = False"); // No result
I know it is easy to do by doing this:
dynamic result = lb.analyze("SomeSource", False, False);
But what if there is more than six or seven named parameter, it would not be great to insert it all manually and change the one I wanted. For example, the python library that I am using have 12 named parameter with default value including two more parameters with no default value.
UPDATED
I also tried:
3. dynamic result = lb.analyze("SomeSource", raw = false); // C# compilation error
To apply keyword arguments use:
lb.analyze("SomeSource", Py.kw("raw", false));
See readme.
Another approach is using C# keyword argument syntax that was recently added to pythonnet:
lb.analyze("SomeSource", raw: false);
Since I am using one function to call python scripts I have used a Listto hold the parameter values. I am also passing in a class name and function name since my python scripts contain multiple classes with multiple functions. I don't use the 'self' parameter in any of my classes, so they are static functions. I am providing a snippet of my code to help you and anyone else out that is using python in .net. I personally use it for communciation with USB.
Here is an example of one of my callers. Ignore the function name but look at how it's calls the ExecuteScript and passing int he parameterset. Notice the list is of type object, incase your paramters are a mix of string/int/bool/objects etc.
public string SendCommand(string comport, string command)
{
try
{
List<object> parameterSet = new() { comport, command };
string result = _pythonService.ExecuteScript<string>("usb", "usb", "sendCommand", parameterSet);
return result;
}
catch (Exception)
{
throw;
}
}
Here is a function that executes the class function
public dynamic? ExecuteScript<T>(string scriptFile, string className, string functionName, List<object> paramset)
{
T? result = default;
try
{
// Location of all the python scripts in the project. lets get the python file we are specifying in the function param
string file = $"{Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)}\\PythonScripts\\{scriptFile}.py";
// This is initalized in the program.cs, but just want to make sure it's initialized in case something happens
if (!PythonEngine.IsInitialized)
{
PythonEngine.Initialize();
Py.GIL();
}
using (var scope = Py.CreateScope())
{
PyObject? pythonReturn; // Our returned PythonObject from the python function call
string code = File.ReadAllText(file); // Get the python file as raw text
var scriptCompiled = PythonEngine.Compile(code, file); // Compile the code/file
scope.Execute(scriptCompiled); // Execute the compiled python so we can start calling it.
PyObject pythonClass = scope.Get(className); // Lets get an instance of the class in python
// Add parameters to the function?
if (paramset != null && paramset.Count > 0)
{
PyObject[] pyParams = new PyObject[paramset.Count]; // This is an array of python parameters passed into a function
// Loop through our incoming c# list of parameters and create PythonObject array .
for (int i = 0; i < paramset.Count; i++)
{
pyParams[i] = paramset[i].ToPython();
}
pythonReturn = pythonClass.InvokeMethod(functionName, pyParams); // Call the function on the class with parameters
}
else // We aren't using parameters here
pythonReturn = pythonClass.InvokeMethod(functionName); // Call the function on the class
// Lets convert our returned pythonObject to that of the object type (C#)
object? netObject = pythonReturn.AsManagedObject(typeof(object));
// A special case of when we want a list back. We will convert the object to the specific type in the caller function
if (typeof(T) == typeof(IList<object>))
{
object[] something = pythonReturn.As<object[]>();
return something;
}
// Convert the c# object to that of what we expect to be returned,. string/int/bool/class
if (netObject != null)
result = (T)netObject; // convert the returned string to managed string object
}
return result;
}
catch (Exception)
{
// Handle your exceptions here
throw;
}
}
If you don't care about the entire function and just want the quick snippet of adding the params:
// Add parameters to the function?
if (paramset != null && paramset.Count > 0)
{
PyObject[] pyParams = new PyObject[paramset.Count]; // This is an array of python parameters passed into a function
// Loop through our incoming c# list of parameters and create PythonObject array .
for (int i = 0; i < paramset.Count; i++)
{
pyParams[i] = paramset[i].ToPython();
}
pythonReturn = pythonClass.InvokeMethod(functionName, pyParams); // Call the function on the class with parameters
}
else // We aren't using parameters here
pythonReturn = pythonClass.InvokeMethod(functionName); // Call the function on the class
I have some code written in Matlab however I wish to call this code from a C# console application.
I do not require any data to be returned from Matlab to my app (although if easy would be nice to see).
There appears to be a few options however not sure which is best. Speed is not important as this will be an automated task.
MATLAB has a .Net interface that's well-documented. What you need to do is covered in the Call MATLAB Function from C# Client article.
For a simple MATLAB function, say:
function [x,y] = myfunc(a,b,c)
x = a + b;
y = sprintf('Hello %s',c);
..it boils down to creating an MLApp and invoking the Feval method:
class Program
{
static void Main(string[] args)
{
// Create the MATLAB instance
MLApp.MLApp matlab = new MLApp.MLApp();
// Change to the directory where the function is located
matlab.Execute(#"cd c:\temp\example");
// Define the output
object result = null;
// Call the MATLAB function myfunc
matlab.Feval("myfunc", 2, out result, 3.14, 42.0, "world");
// Display result
object[] res = result as object[];
Console.WriteLine(res[0]);
Console.WriteLine(res[1]);
Console.ReadLine();
}
}
I'm just learning about Lua and trying to integrate it with C# and mono (on Linux). After some looking around, I found AluminumLua as a wrapper to do so.
I've successfully being able to call from lua to C#, but I can't see the way to call from C# to lua:
lua (test.lua):
HelloWorld()
function print_test()
print("hi")
return 1
end
C#
var context = new LuaContext ();
context.AddBasicLibrary ();
context.AddIoLibrary ();
context.SetGlobal ("HelloWorld", LuaObject.FromDelegate(new Action(HelloWorld)));
var parser = new LuaParser (context, "test.lua");
parser.Parse ();
...
public static void HelloWorld() {
Console.Write("HelloWorld");
}
That's cool, but... How can I call the function "print_test", get its output result from C#?
From looking at the source, LuaContext has a Get method which returns a LuaObject. After you have a reference to that LuaObject you can try to turn it into a LuaFunction using AsFunction and IsFunction.
Something along the lines of this should work:
// ...
var print_test = context.Get("print_test");
if (print_test.IsFunction)
{
print_test.AsFunction()(null);
}
else
{
Console.Write("print_test not a lua function!");
}
// ...
I am writing a scripting language, i've done the lexer and parser and i want to dynamically execute in the memory.
Lets say i have something like
function Hello(World)
{
Print(world);
}
var world = "World";
var boolean = true;
if(boolean == true)
{
Print("True is True");
}
else
{
Print("False is True");
}
Hello(world);
what would be the best way to execute this snippet i'ved tried
1) OpCode Il Generation (i couldn't get if statement to work or anything other than Print function)
2) RunSharp, i cannot do the functions cause the way i can do it i have no idea how.
If anyone could point me to the right direction!
Alittle Code will help
Link to resource (not something like IronPython) would be also good
your script language like JavaScript,if it dynamic compile in memory.
example:
//csc sample.cs -r:Microsoft.JScript.dll
using System;
using System.CodeDom.Compiler;
using Microsoft.JScript;
class Sample {
static public void Main(){
string[] source = new string[] {
#"import System;
class JsProgram {
function Print(mes){
Console.WriteLine(mes);
}
function Hello(world){
Print(world);
}
function proc(){
var world = ""World"";
var bool = true;
if(bool == true){
Print(""True is True"");
}
else{
Print(""False is True"");
}
Hello(world);
}
}"
};
var compiler = new JScriptCodeProvider();
var opt = new CompilerParameters();
opt.ReferencedAssemblies.Add("System.dll");
opt.GenerateExecutable = false;
opt.GenerateInMemory = true;
var result = compiler.CompileAssemblyFromSource(opt, source);
if(result.Errors.Count > 0){
Console.WriteLine("Compile Error");
return;
}
var js = result.CompiledAssembly;
dynamic jsProg = js.CreateInstance("JsProgram");
jsProg.proc();
/*
True is True
World
*/
}
}
generate c# source and compile it :-)
http://support.microsoft.com/kb/304655
If I understand you right, you want to compile and run the code on runtime? then you could try http://www.csscript.net/index.html , its an example on the same page linked.