1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C#からJScriptのevalを呼び出す

Posted at

evalつかって 1+2*3+4 みたいな式をユーザーが指定して、計算できるようにする。

「source」の中をいじれば他のこともできそう。(コンパイルエラーの例外処理追加要りそう)

サンプルコード

EvalTest.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
using System.Threading;
using System.Threading.Tasks;
using System.Reflection;
using System.CodeDom.Compiler;


public class ExprTest
{
    static SimpleParser sp = new SimpleParser();

    public class SimpleParser
    {
        dynamic m_evaluator = null;
        
        public SimpleParser()
        {
            string source = @"package Evaluator{class Evaluator{public function MyEval(expr:String){return eval(expr);}}}";
            CodeDomProvider prov = new Microsoft.JScript.JScriptCodeProvider();
            CompilerParameters cparam = new CompilerParameters();
            cparam.GenerateInMemory = true;
            CompilerResults result = prov.CompileAssemblyFromSource(cparam, source);
            Assembly asm = result.CompiledAssembly;
            m_evaluator = Activator.CreateInstance(asm.GetType("Evaluator.Evaluator"));
        }
        
        public object eval(string exp)
        {
            try {
                return m_evaluator.MyEval(exp); // CompileAssemblyFromSource に渡した source の中の function の名前(MyEval)をメソッド名として指定
            }
            catch ( Microsoft.JScript.JScriptException e ) { // コンパイルにするには Microsoft.Vsa.dll を参照に追加する必要がある
                Console.WriteLine(e);
            }
            return null;
        }
    }
    
    [STAThread]
    public static void Main(string[] args)
    {
        object a = sp.eval("1+2*3+4");
        
        if ( a != null ) {
            Console.Write("ValueType: ");
            Console.WriteLine(a.GetType());
            Console.Write("Value: ");
            Console.WriteLine(a);
        }
    }
}

コンパイル方法

csc.exe ^
  /r:C:\Windows\assembly\GAC_MSIL\Microsoft.JScript\8.0.0.0__b03f5f7f11d50a3a\Microsoft.JScript.dll ^
  /r:C:\Windows\assembly\GAC_MSIL\Microsoft.Vsa\8.0.0.0__b03f5f7f11d50a3a\Microsoft.Vsa.dll ^
  EvalTest.cs

参考サイト

http://espresso3389.hatenablog.com/entry/20080713/1215920756
http://gushwell.ldblog.jp/archives/52012439.html

補足

参考サイトの内容で事足りている気がしますが、
dynamic型を使って書き直したのと、それに伴ってexceptionの型を変更しています。

あと、下記のようにstaticでnewすることで、ExprTestクラスの実体を複数作ったとしても
evalの実体を1個で済ませることができているはず。

static SimpleParser sp = new SimpleParser();
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?