Windows apps
Collapse the table of content
Expand the table of content
Information
The topic you requested is included in another documentation set. For convenience, it's displayed below. Choose Switch to see the topic in its original location.

ILGenerator::EmitCall Method (OpCode, MethodInfo^, array<Type^>^)

 

Puts a call or callvirt instruction onto the Microsoft intermediate language (MSIL) stream to call a varargs method.

Namespace:   System.Reflection.Emit
Assembly:  mscorlib (in mscorlib.dll)

public:
virtual void EmitCall(
	OpCode opcode,
	MethodInfo^ methodInfo,
	array<Type^>^ optionalParameterTypes
)

Parameters

opcode
Type: System.Reflection.Emit::OpCode

The MSIL instruction to be emitted onto the stream. Must be OpCodes::Call, OpCodes::Callvirt, or OpCodes::Newobj.

methodInfo
Type: System.Reflection::MethodInfo^

The varargs method to be called.

optionalParameterTypes
Type: array<System::Type^>^

The types of the optional arguments if the method is a varargs method; otherwise, null.

Exception Condition
ArgumentException

opcode does not specify a method call.

ArgumentNullException

methodInfo is null.

InvalidOperationException

The calling convention for the method is not varargs, but optional parameter types are supplied. This exception is thrown in the .NET Framework versions 1.0 and 1.1, In subsequent versions, no exception is thrown.

The EmitCall method is used to emit calls to varargs methods because there is no overload of the Emit method that specifies the parameter types of the variable arguments.

To emit calls to methods that do not use the VarArgs calling convention, use the Emit(OpCode, MethodInfo^) method overload.

Beginning with the .NET Framework version 2.0, the EmitCall method does not throw an exception when optional parameter types are specified for a method that is not varargs. InvalidProgramException is thrown when the call is executed.

The following code example emits two methods, a varargs method and a method that calls the varargs method. The EmitCall method is used to emit the call to the varargs method.

using namespace System;
using namespace System::Reflection;
using namespace System::Reflection::Emit;

void main() 
{
    String^ name = "InMemory";

    AssemblyBuilder^ asmBldr = 
       AppDomain::CurrentDomain->DefineDynamicAssembly(gcnew AssemblyName(name), 
          AssemblyBuilderAccess::Run);
    ModuleBuilder^ modBldr = asmBldr->DefineDynamicModule(name); 

    TypeBuilder^ tb = modBldr->DefineType("DemoVararg");

    // Create a vararg method with no return value and one 
    // string argument. (The string argument type is the only
    // element of an array of Type objects.)
    //
    MethodBuilder^ mb1 = tb->DefineMethod("VarargMethod",
        MethodAttributes::Public | MethodAttributes::Static,
        CallingConventions::VarArgs,
        nullptr, 
        gcnew array<Type^> { String::typeid });

    ILGenerator^ il1 = mb1->GetILGenerator();

    LocalBuilder^ locAi = il1->DeclareLocal(ArgIterator::typeid);
    LocalBuilder^ locNext = il1->DeclareLocal(bool::typeid);

    Label labelCheckCondition = il1->DefineLabel();
    Label labelNext = il1->DefineLabel();

    // Load the fixed argument and print it.
    il1->Emit(OpCodes::Ldarg_0);
    il1->Emit(OpCodes::Call, Console::typeid->GetMethod("Write", 
         gcnew array<Type^> { String::typeid }));

    // Load the address of the local variable represented by
    // locAi, which will hold the ArgIterator.
    il1->Emit(OpCodes::Ldloca_S, locAi);

    // Load the address of the argument list, and call the 
    // ArgIterator constructor that takes an array of runtime
    // argument handles. 
    il1->Emit(OpCodes::Arglist);
    il1->Emit(OpCodes::Call, ArgIterator::typeid->GetConstructor(
         gcnew array<Type^> { RuntimeArgumentHandle::typeid }));

    // Enter the loop at the point where the remaining argument
    // count is tested.
    il1->Emit(OpCodes::Br_S, labelCheckCondition);

    // At the top of the loop, call GetNextArg to get the next 
    // argument from the ArgIterator. Convert the typed reference
    // to an object reference and write the object to the console.
    il1->MarkLabel(labelNext);
    il1->Emit(OpCodes::Ldloca_S, locAi);
    il1->Emit(OpCodes::Call, ArgIterator::typeid->GetMethod("GetNextArg", Type::EmptyTypes));
    il1->Emit(OpCodes::Call, TypedReference::typeid->GetMethod("ToObject"));
    il1->Emit(OpCodes::Call, Console::typeid->GetMethod("Write", 
         gcnew array<Type^> { Object::typeid }));

    il1->MarkLabel(labelCheckCondition);
    il1->Emit(OpCodes::Ldloca_S, locAi);
    il1->Emit(OpCodes::Call, ArgIterator::typeid->GetMethod("GetRemainingCount"));

    // If the remaining count is greater than zero, go to
    // the top of the loop.
    il1->Emit(OpCodes::Ldc_I4_0);
    il1->Emit(OpCodes::Cgt);
    il1->Emit(OpCodes::Stloc_1);
    il1->Emit(OpCodes::Ldloc_1);
    il1->Emit(OpCodes::Brtrue_S, labelNext);

    il1->Emit(OpCodes::Ret);

    // Create a method that contains a call to the vararg 
    // method.
    MethodBuilder^ mb2 = tb->DefineMethod("CallVarargMethod",
        MethodAttributes::Public | MethodAttributes::Static,
        CallingConventions::Standard,
        nullptr, Type::EmptyTypes);

    ILGenerator^ il2 = mb2->GetILGenerator();

    // Push arguments on the stack: one for the fixed string
    // parameter, and two for the list.
    il2->Emit(OpCodes::Ldstr, "Hello ");
    il2->Emit(OpCodes::Ldstr, "world ");
    il2->Emit(OpCodes::Ldc_I4, 2006);

    // Call the vararg method, specifying the types of the 
    // arguments in the list.
    il2->EmitCall(OpCodes::Call, mb1, 
        gcnew array<Type^> { String::typeid, int::typeid });

    il2->Emit(OpCodes::Ret);

    Type^ type = tb->CreateType();
    type->GetMethod("CallVarargMethod")->Invoke(nullptr, nullptr);
}

/* This code example produces the following output:

Hello world 2006
 */

.NET Framework
Available since 1.1
Portable Class Library
Supported in: portable .NET platforms
Silverlight
Available since 2.0
Windows Phone Silverlight
Available since 7.1
Return to top
Show:
© 2017 Microsoft