Note that there are some explanatory texts on larger screens.

plurals
  1. POMSIL - how do you invoke a private method from MSIL?
    text
    copied!<p>I'm writing a "weak event factory" - code which converts any Delegate into a new delegate with an identical signature, but with implementing a WeakReference on the target. I'm using MSIL to avoid calls to Delegate.CreateDelegate (which performance have shown to be slow).</p> <p>The weak reference delegates work perfectly <em>as long as</em> the underlying method (the <em>Method</em> of the original delegate), was declared public. As soon as a private or anonymous method is used, the MSIL bombs at run time with a <strong>MethodAccessException</strong>.</p> <p>Using compiled expression trees, I've been able to invoke private methods, so it must be possible to dynamically emit MSIL which invokes a private method. ...so what's wrong with the following?</p> <pre><code> // var target = this.Target il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Callvirt, targetPropGetter); il.Emit(OpCodes.Stloc, ilTarget); // if(target != null) // { il.Emit(OpCodes.Ldloc, ilTarget); il.Emit(OpCodes.Brfalse_S, ilIsNullLabel); // Method( @target, parm1, parm2 ...); il.Emit(OpCodes.Ldloc, ilTarget); // this = Target short argIndex = 1; foreach (var parm in delgParams) // push all other args il.Emit(OpCodes.Ldarg, argIndex++); il.Emit(OpCodes.Callvirt, delegat.Method); // &lt;-- Bombs if method is private il.Emit(OpCodes.Ret); // } il.MarkLabel(ilIsNullLabel); </code></pre> <p>So what's the secret to invoking a private member? Reflection can do it, expression trees can do it... why is the above code failing?</p> <hr> <p>EDIT: Much thanks to all of you who provided answers here. It turns out that the only solution which consistently worked in my context was to use generic delegates (Action)... because Action originates from the mscorlib, the JIT seems perfectly happy to let <em>it</em> invoke a private method. try using your own delegate and the JIT pukes just the same as if you emit a Call or Callvirt directly to the target.</p> <p>Anyone who's interested in seeing the working code can head over to <a href="http://sharpobservation.codeplex.com/" rel="noreferrer">codeplex</a> - the answers given here helped in implementing the WeakDelegate capabilities.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload