Created
July 3, 2020 16:49
-
-
Save ForNeVeR/302b12bcf52ace57d8bfb1703f26e501 to your computer and use it in GitHub Desktop.
Call __arglist method with Reflection.Emit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using System.Reflection; | |
using System.Reflection.Emit; | |
namespace ConsoleApp4 | |
{ | |
public class Program | |
{ | |
public static void Callee(__arglist) | |
{ | |
var iterator = new ArgIterator(__arglist); | |
while (iterator.GetRemainingCount() > 0) | |
{ | |
Console.WriteLine( | |
__refvalue(iterator.GetNextArg(), string)); | |
} | |
} | |
static void Main() | |
{ | |
var args = new object[] {"a", "b", "×"}; | |
var callee = typeof(Program).GetMethod("Callee", BindingFlags.Static|BindingFlags.Public); | |
MakeCall(callee, args); | |
} | |
private static void MakeCall(MethodInfo callee, object[] args) | |
{ | |
var name = new AssemblyName("ZOG"); | |
var ass = AssemblyBuilder.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); | |
var moduleBuilder = ass.DefineDynamicModule("COG"); | |
var typeBuilder = moduleBuilder.DefineType("MUG", | |
TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.BeforeFieldInit); | |
var parameterTypes = args.Select(δ => δ.GetType()).ToArray(); | |
var methodBuilder = typeBuilder.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, | |
typeof(void), parameterTypes); | |
var ilGenerator = methodBuilder.GetILGenerator(); | |
GeneratedCode(ilGenerator, callee, parameterTypes); | |
var mug = typeBuilder.CreateType(); | |
var main = mug.GetMethod("Main", BindingFlags.Public | BindingFlags.Static); | |
main.Invoke(null, args); | |
} | |
private static void GeneratedCode(ILGenerator ilGenerator, MethodInfo callee, Type[] types) | |
{ | |
for (var i = 0; i < types.Length; ++i) | |
ilGenerator.Emit(OpCodes.Ldarg, (short)i); | |
ilGenerator.EmitCall(OpCodes.Call, callee, types); | |
ilGenerator.Emit(OpCodes.Ret); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment