May 18, 2011

Matlab,C# and DynamicObject a perfect marriage!

I am using an old version of matlab (7.5). I have been porting some code to C# but I wanted to make sure my plots were correct. After writing _m.Execute about 10 times I decided to write a wrapper for plot. I quickly started needing many commands and thought, there has to be an easier way. What if we can write code like this in C#?

static void Main(string[] args)
{
dynamic m = new Matlab();
m.cd(Environment.CurrentDirectory);
m.close();
m.clear();
m.figure(1);
m.plot(new double[] { 1, 2, 3 }, new double[] { 3, 1, 3 });
m.title("plot title");
var z=m.zeros(2,100);
var o = m.ones(2, 100);

}

Well in fact you can if we do some dancing! First, get familiar with the wonderful class that Microsoft built called DynamicObject. This class allows us to dynamically dispatch calls anywhere we want, in our case, MATLAB. We get the call to TryInvokeMember. From there we use the binder to tell us what we are doing and then we execute it. There is still along way for this project to go, but for now, I’ve got C# friendly code calling matlab!


using System.Text;
usingSystem.Dynamic;

namespaceMatlabExtensions
{
    public classMatlab : DynamicObject
  
{
        MLApp.MLApp _a;
        publicMatlab()
        {
            _a = newMLApp.MLApp();
        }

        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out objectresult)
        {
            StringBuilder command = newStringBuilder();
            command.Append(binder.Name);
            command.Append("(");
            int idx = 0;
            foreach (var arg inargs)
            {
                stringvar = string.Format("arg{0}", idx++);
                _a.PutWorkspaceData(var, "base", arg);
                command.Append(var);
                command.Append(",");
            }

            stringexec = command.ToString();
            exec = exec.TrimEnd(',') + ")";
            _a.Execute(exec);
            try
          
{
                result = _a.GetVariable("ans", "base");
            }
            catch{ result = null; }
           
            return true;
        }
    }
}

A small note, you will need to reference the matlab com library.


image

No comments:

Post a Comment

Followers