Note that there are some explanatory texts on larger screens.

plurals
  1. POInvalidProgramException trying to call a static method via Reflection.Emit
    primarykey
    data
    text
    <p>I'm trying to make a dynamic type that basically wraps some methods on a static class. I've created a static method called Wrap that has a generic parameter which should be an interface, and one normal parameter which is the type of class that has the static methods.</p> <p>e.g.</p> <pre><code>IInterfaceTest obj = StaticInterface.Wrap&lt;IInterfaceTest&gt;(typeof(StaticClassNameHere)); obj.TestInterfaceMethod(); </code></pre> <p>But the code I'm generating is obviously broken somewhere as I get an InvalidProgramException when I call the method.</p> <p>I based my code on the ILDasm output of a test class I made, and as far as I can tell, I'm outputting the same code. But it ain't working...</p> <pre><code>public static class StaticInterface { private static AssemblyBuilder _asm = null; private static ModuleBuilder _mod = null; private static Type _thisType = typeof(StaticInterface); private static int _count = 0; public static T Wrap&lt;T&gt;(Type type) { ILGenerator ilgen; if (_asm == null) { _asm = AppDomain.CurrentDomain.DefineDynamicAssembly(new System.Reflection.AssemblyName(_thisType.Name), AssemblyBuilderAccess.Run); _mod = _asm.DefineDynamicModule(_thisType.Name); } string newTypeName = _thisType.Name + "._" + _count++; TypeBuilder typBuilder = _mod.DefineType(newTypeName, System.Reflection.TypeAttributes.Class | System.Reflection.TypeAttributes.Public); typBuilder.AddInterfaceImplementation(typeof(T)); ConstructorBuilder conBuilder = typBuilder.DefineDefaultConstructor(System.Reflection.MethodAttributes.Public); foreach (MethodInfo method in typeof(T).GetMethods()) { ParameterInfo[] parameters = method.GetParameters(); Type[] paramTypes = new Type[parameters.Length]; for (int j = 0; j &lt; parameters.Length; j++) { paramTypes[j] = parameters[j].ParameterType; } MethodBuilder mth = typBuilder.DefineMethod(method.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Final, method.ReturnType, paramTypes); ilgen = mth.GetILGenerator(); ilgen.Emit(OpCodes.Nop); for (short j = 0; j &lt; parameters.Length; j++) { ilgen.Emit(OpCodes.Ldarg, j + 1); } MethodInfo callMeth = type.GetMethod(method.Name, BindingFlags.Public | BindingFlags.Static, null, paramTypes, null); ilgen.EmitCall(OpCodes.Call, callMeth, null); if (method.ReturnType != null &amp;&amp; method.ReturnType != typeof(void)) { ilgen.Emit(OpCodes.Stloc_0); Label end = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Br_S, end); ilgen.MarkLabel(end); ilgen.Emit(OpCodes.Ldloc_0); } ilgen.Emit(OpCodes.Ret); } typBuilder.CreateType(); return (T)_asm.CreateInstance(newTypeName, false, BindingFlags.Public | BindingFlags.Instance, null, null, null, null); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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