Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiling lambdas and invoking delegates on the device in Monotouch

I am currently porting a .NET codebase in MonoTouch and I'm currently working on a method that receives an Expression<T>. I'm trying to compile it, and then dynamically invoke it.

Here's what I did:

// Here's an example of what I could receive
Expression<Action<int>> expression = (a => Console.WriteLine (a * 2));

// And here's what I'm trying to do to invoke it
expression.Compile().DynamicInvoke(6);

This works fine in the iOS Simulator, the result "12" is printed in my console. But then I tried it on an iPad, and I received the following exception.

Object reference not set to an instance of an object
   at System.Linq.jvm.Runner.CreateDelegate ()
   at System.Linq.Expressions.LambdaExpression.Compile ()
   at System.Linq.Expressions.Expression`1[System.Action`1[System.Int32]].Compile ()
   at TestSolution2.AppDelegate.FinishedLaunching (MonoTouch.UIKit.UIApplication app, MonoTouch.Foundation.NSDictionary options)

What am I doing wrong and how could I make it work?

like image 434
Louis Boux Avatar asked Feb 02 '23 15:02

Louis Boux


1 Answers

Not familiar with System.Linq.Expressions, but presumably it involves runtime code generation.

There is no JIT in iOS, all code must be compiled ahead-of-time. The same restriction does not apply in the simulator, hence your code runs there.

See here.

The Compile() method is not supported on the iOS device, since the device prevents the JIT engine from running. Compile itself is implemented using System.Reflection.Emit and this in turns requires a functioning JIT. So the above code would never wor kwith expression trees.

like image 68
TheNextman Avatar answered Feb 06 '23 15:02

TheNextman