Re: Reflection.Emit Call

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance



Fabio wrote:

"Barry Kelly" <barry.j.kelly@xxxxxxxxx> ha scritto nel messaggio

Hi all!

Someone can tell me how to add a

call instance <method>

The 'instance' is part of the method ref/def. If you have a MethodInfo
that refers to an instance method, then you get 'instance', if it's
static, you get 'static'. As long as you got the right MethodInfo, you
don't need to worry about it.

mmm... the method in question is Int32.ToString() that is an instance method
and it is (i think) a "callvirt" method, since it is an override of
object.ToString() (I think I can correctly get that it is an override
because method.IsVirtual and method.IsHideBySig are true).

So, if I call Emit(CallVirt... it works, but the IlAsm tell me that the
right way to do it is call instance, and if I replace in the code callvirt
with call instance ilasm compile without claims.

So, my question is: can I do a Emit(Call ... instance?

What's wrong with this?

---8<---
static void Write42(ILGenerator cg)
{
LocalBuilder x = cg.DeclareLocal(typeof(Int32));
cg.Emit(OpCodes.Ldc_I4, 42);
cg.Emit(OpCodes.Stloc, x);
cg.Emit(OpCodes.Ldloca, x);
cg.Emit(OpCodes.Call,
typeof(System.Int32).GetMethod("ToString",
new Type[0]));
cg.Emit(OpCodes.Call,
typeof(System.Console).GetMethod("WriteLine",
new Type[] { typeof(string) }));
}
--->8---

Does it do something different to what you want?

I suggest you read the specification for 'call', in Partition III
section 3.19 of ECMA 335. In particular:

"The metadata token carries sufficient information to determine whether
the call is to a static method, an instance method, a virtual method, or
a global function."

[...]

"It is valid to call a virtual method using call (rather than callvirt);
this indicates that the method is to be resolved using the class
specified by method rather than as specified dynamically from the object
being invoked"

-- Barry

--
http://barrkel.blogspot.com/
.



Relevant Pages

  • Re: PEVerify generates improper ERROR
    ... But the C# compiler is using call, not callvirt, to call into your sealed ... no distinction between call and callvirt. ... Despite the fact that ToString is a virtual method override. ...
    (microsoft.public.dotnet.framework.clr)
  • Re: Reflection.Emit Call
    ... LocalBuilder x = cg.DeclareLocal); ... For virtual methods you have to use 'callvirt', and for instance methods ... "It is valid to call a virtual method using call; ...
    (microsoft.public.dotnet.framework.clr)