mardi 20 février 2018

C# Bind dynamic Function to Event

I have a really weird problem here. I Want to bind a function to a Event. But the Event and the Function to be bound are only compatible through a proxy function and at start I have just the names as String.

At first: This is the delegate and the Event:

    public delegate void ControllerInteractionEventHandler(object sender, ControllerInteractionEventArgs e);
[...]
public class VRTK_ControllerEvents : MonoBehaviour{
[...]
        public event ControllerInteractionEventHandler TriggerPressed;
[...]

Then I have This function wich I want to be called:

public void Export_LoadObject(string guid, string PrefabName, string sender = null){[...]}

Normally the Binding wouldnt be a Problem. Now lets see what we have:

    private void addEventBinding(string obj, string component, string eventName, string functionName, string param){
    GameObject go = m_Instance_Id.getObject<GameObject>(obj);

            dynamic comp = go.GetComponents<Component>().Where(x => x.GetType().Name.Equals(component)).ToArray()[0];
            EventInfo eventInfo = comp.GetType().GetEvent(eventName);

            Type[] handlerArgs = { typeof(object), typeof(ControllerInteractionEventArgs) };
            method = new DynamicMethod("EventMethod", typeof(void), handlerArgs);
            Type[] paramArgs;
            paramArgs = new Type[param.Split(',').Length];
            for (int i = 0; i < paramArgs.Length; i++)
            {
                paramArgs[i] = typeof(string);
            }


            MethodInfo calling = typeof(WebApi).GetMethod("Export_" + functionName, paramArgs);

            ILGenerator il = method.GetILGenerator(256);
            for (int i = 0; i < paramArgs.Length; i++) {
                FieldInfo f = typeof(OpCodes).GetField("Ldarg_" + i);
                OpCode code = (OpCode)f.GetValue(null);
                il.Emit(code);
            }
            il.EmitCall(OpCodes.Call, calling, null);
            il.Emit(OpCodes.Ret);



            RegisterEventDelegate handler = (RegisterEventDelegate)method.CreateDelegate(typeof(RegisterEventDelegate));
            eventInfo.AddEventHandler(comp, handler);

As u can see I have to find everything at runntime and I never used ILGenerator bevore.

I get the following error:

InvalidProgramException: Invalid IL code in (wrapper dynamic-method) object:EventMethod (object,VRTK.ControllerInteractionEventArgs): IL_0002: ldarg.2

System.Delegate.CreateDelegate (System.Type type, System.Object firstArgument, System.Reflection.MethodInfo method, System.Boolean throwOnBindFailure, System.Boolean allowClosed) (at <9c9f068c46c64ffd91fda7af157b4d15>:0) System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodInfo method, System.Boolean throwOnBindFailure) (at <9c9f068c46c64ffd91fda7af157b4d15>:0) System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodInfo method) (at <9c9f068c46c64ffd91fda7af157b4d15>:0) System.Reflection.Emit.DynamicMethod.CreateDelegate (System.Type delegateType) (at <9c9f068c46c64ffd91fda7af157b4d15>:0) (wrapper dynamic-method) System.Object:CallSite.Target (System.Runtime.CompilerServices.Closure,System.Runtime.CompilerServices.CallSite,object,System.Type) System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet] (System.Runtime.CompilerServices.CallSite site, T0 arg0, T1 arg1) (at <11c1c8f1ba1046b191f565f88728429e>:0)

I didnt really get whats wrong about it, can anyone help?





Aucun commentaire:

Enregistrer un commentaire