public static Ref::MethodInfo LoadMethod(string file, string className, string methodName, string[] paramTypes) { // TODO: 色々な場所の候補 System.Type type = LoadType(file, className); if (type == null) { throw new System.Exception("指定した型は見つかりません。"); } // メソッドの検索 Ref::BindingFlags BF = Ref::BindingFlags.NonPublic | Ref::BindingFlags.Public | Ref::BindingFlags.Static; System.Type[] tParamTypes = new System.Type[paramTypes.Length]; for (int i = 0; i < paramTypes.Length; i++) { System.Type tParam = NameToPrimitiveType(paramTypes[i]); if (tParam == null) { throw new System.FormatException("関数の引数型を認識できません。"); } } Ref::MethodInfo m = type.GetMethod(methodName, BF, null, tParamTypes, null); if (m == null) { throw new System.MissingMethodException("指定されたメソッドは見つかりません。"); } return(m); }
private Emit::DynamicMethod CreateDynamicMethod(string name) { if (!typeof(System.Delegate).IsAssignableFrom(typeof(D))) { throw new System.InvalidProgramException("DynamicMethodCreator の第二型引数はデリゲート型である必要があります。"); } Ref::MethodInfo minfo = typeof(D).GetMethod("Invoke"); // 引数の型 Gen::List <System.Type> param_types = new System.Collections.Generic.List <System.Type>(); if (!is_static) { param_types.Add(typeof(T)); } foreach (Ref::ParameterInfo p in minfo.GetParameters()) { param_types.Add(p.ParameterType); } return(new Emit::DynamicMethod( typeof(T).FullName + "::" + name, minfo.ReturnType, param_types.ToArray(), typeof(T) )); }
public Reader(CustomReadAttribute attr, System.Type type) { const Ref::BindingFlags BF = Ref::BindingFlags.Public | Ref::BindingFlags.NonPublic | Ref::BindingFlags.Static; this.info = (Ref::MethodInfo)GetMemberInfo(type, attr.method, BF, InvokingFlags.Method_ParamAccessor); this.type = type; }
//=========================================================== // 初期化 //=========================================================== public TestMethod(Ref::MethodInfo minfo) { CM::DescriptionAttribute[] attrs = (CM::DescriptionAttribute[])minfo.GetCustomAttributes(typeof(CM::DescriptionAttribute), false); string desc = attrs.Length == 0?"":attrs[0].Description; this.info = minfo; this.description = desc; }
public object InvokeD(System.Delegate deleg, object _arguments) { ScriptObject arguments = win.ToScriptObject(_arguments); Ref::ParameterInfo[] pinfos = deleg.Method.GetParameters(); object[] args = new object[pinfos.Length]; for (int i = 0; i < pinfos.Length; i++) { System.Type ptype = pinfos[i].ParameterType; args[i] = arguments[i.ToString()].Value; if (args[i] == null) { // 既定値の採用 object[] attrs = pinfos[i].GetCustomAttributes(typeof(CM::DefaultValueAttribute), false); if (attrs.Length != 0) { args[i] = ((CM::DefaultValueAttribute)attrs[0]).Value; } else if (ptype == typeof(Event)) { // Event Object の場合 args[i] = win.@event; } } else if (!ptype.IsAssignableFrom(args[i].GetType())) { // 自動型変換 if (typeof(MshtmlObject).IsAssignableFrom(ptype)) { try{ Ref::MethodInfo fromObj = ptype.GetMethod("FromObj", Ref::BindingFlags.Static | Ref::BindingFlags.Public); args[i] = fromObj.Invoke(null, new object[] { args[i] }); }catch {} } else if (typeof(ScriptObject) == ptype) { args[i] = new ScriptObject(win, args[i]); } } } object ret; try{ ret = deleg.Method.Invoke(deleg.Target, args); }catch (System.Reflection.TargetInvocationException e) { if (e.InnerException == null) { throw; } throw e.InnerException; } return(ret); }
public override void Write(object value, StreamAccessor accessor) { const Ref::BindingFlags BF = Ref::BindingFlags.Public | Ref::BindingFlags.NonPublic | Ref::BindingFlags.Static; Ref::MethodInfo info = (Ref::MethodInfo)GetMemberInfo(value.GetType(), this.method, BF, InvokingFlags.Method_ParamObjectAccessor); try{ info.Invoke(null, new object[] { value, accessor }); }catch (System.Exception e) { __dll__.log.WriteError(e, "独自定義ストリーム書込で例外が発生しました。"); throw; } }
/// <summary> /// 仮想関数呼び出しを出力します。 /// </summary> /// <param name="type">仮想メソッドが宣言されているクラスを指定します。</param> /// <param name="is_private">仮想メソッドが private/internal であるか否かを指定します。</param> /// <param name="is_static">静的メソッドであるか否かを指定します。</param> /// <param name="methodName">仮想メソッドの名前を指定します。</param> /// <param name="param_types">仮想メソッドの引数の型を指定します。</param> public void EmitCallvirt( System.Type type, bool is_private, bool is_static, string methodName, params System.Type[] param_types ) { Ref::BindingFlags BINDING = (is_private?Ref::BindingFlags.NonPublic:Ref::BindingFlags.Public) | (is_static?Ref::BindingFlags.Static:Ref::BindingFlags.Instance); Ref::MethodInfo method = type.GetMethod(methodName, BINDING, null, param_types, null); gen.Emit(Emit::OpCodes.Callvirt, method); }
public static bool IsTestable(Ref::MethodInfo minfo) { Ref::ParameterInfo[] pinfos = minfo.GetParameters(); if (pinfos.Length > 1) { return(false); } if (pinfos.Length == 1) { return(pinfos[0].ParameterType == typeof(afh.Application.Log)); } return(false); }
public static Ref::MethodInfo LoadMethod(string file, string className, string methodName, int numOfParams) { // TODO: 色々な場所の候補 System.Type type = LoadType(file, className); if (type == null) { throw new System.Exception("指定した型は見つかりません。"); } // メソッドの検索 Ref::BindingFlags BF = Ref::BindingFlags.NonPublic | Ref::BindingFlags.Public | Ref::BindingFlags.Static; Ref::MethodInfo m = null; foreach (Ref::MethodInfo minfo in type.GetMethods(BF)) { if (minfo.Name != methodName) { continue; } // 引数型を check Ref::ParameterInfo[] pinfos = minfo.GetParameters(); int i; for (i = 0; i < pinfos.Length; i++) { if (!IsPrimitive(pinfos[i].ParameterType)) { break; } } if (i != pinfos.Length) { continue; } if (m != null) { throw new System.Reflection.AmbiguousMatchException("オーバーロードを特定できません。"); } m = minfo; } if (m == null) { throw new System.MissingMethodException("指定されたメソッドは見つかりません。"); } return(m); }
public static void analyze_generic_PrimitiveTypes(afh.Application.Log log) { const Ref::BindingFlags BF = Ref::BindingFlags.Static | Ref::BindingFlags.NonPublic; Ref::MethodInfo gen_meth = typeof(UnitTest).GetMethod("analyze_genprim_IsLargerThan", BF); Ref::MethodInfo nrm_meth = typeof(UnitTest).GetMethod("analyze_genprim_IsLargerThanPrim", BF); log.WriteLine("generic<T> body"); log.DumpBytes(gen_meth.GetMethodBody().GetILAsByteArray()); // null らしい log.WriteLine("generic<int> body"); log.DumpBytes(gen_meth.MakeGenericMethod(typeof(int)).GetMethodBody().GetILAsByteArray()); log.WriteLine("normal body"); log.DumpBytes(nrm_meth.GetMethodBody().GetILAsByteArray()); // 実際に実験 log.WriteLine(analyze_genprim_IsLargerThan <int>(10, 8)); log.WriteLine(analyze_genprim_IsLargerThanPrim(10, 8)); }
public override object Read(System.Type type, StreamAccessor accessor) { const Ref::BindingFlags BF = Ref::BindingFlags.Public | Ref::BindingFlags.NonPublic | Ref::BindingFlags.Static; Ref::MethodInfo info = (Ref::MethodInfo)GetMemberInfo(type, this.method, BF, InvokingFlags.Method_ParamAccessor); object ret; try{ ret = info.Invoke(null, new object[] { accessor }); }catch (System.Exception e) { __dll__.log.WriteError(e, "独自定義ストリーム読込で例外が発生しました。"); throw; } if (!type.IsInstanceOfType(ret)) { throw new System.InvalidCastException(); } return(ret); }
/// <summary> /// メソッドの名前及びシグニチャ情報を文字列として取得します。 /// </summary> /// <param name="meth">情報を文字列にするメソッドを指定します。</param> /// <returns>メソッドの情報を文字列にして返します。</returns> public static string GetMethodSignature(Ref::MethodBase meth) { //string dll=System.IO.Path.GetFileName(m.DeclaringType.Assembly.CodeBase); string ret = ""; if (meth.IsStatic) { ret += "static "; } Ref::MethodInfo minfo = meth as Ref::MethodInfo; if (minfo != null) { ret += CSharpName(minfo.ReturnType) + " "; } //"<"+dll+"> "+ return(ret + CSharpName(meth) + "(" + Types.GetParameterList(meth) + ");"); }
public static void testComposedType(afh.Application.Log log) { System.Action <System.Type> write = delegate(System.Type t){ testComposedType_write(t, log); }; Ref::MethodInfo minfo = typeof(UnitTest).GetMethod("testComposedType_meth", Ref::BindingFlags.Static | Ref::BindingFlags.NonPublic); Ref::ParameterInfo[] pinfos = minfo.GetParameters(); log.Lock(); write(typeof(int *)); write(pinfos[0].ParameterType); write(pinfos[1].ParameterType); write(pinfos[2].ParameterType); log.Unlock(); Ref::MethodInfo minfo2 = pinfos[2].ParameterType.GetMethod("Method", Ref::BindingFlags.Static | Ref::BindingFlags.Public); log.WriteLine(Types.GetMethodSignature(minfo)); log.WriteLine(Types.GetMethodSignature(minfo2)); }
//=========================================================== // 初期化 //=========================================================== public static BenchMethodAttribute GetAttribute(Ref::MethodInfo minfo, afh.Application.Log log) { object[] attrs = minfo.GetCustomAttributes(typeof(BenchMethodAttribute), false); if (attrs.Length == 0) { return(null); } BenchMethodAttribute attr = (BenchMethodAttribute)attrs[0]; if (!minfo.IsStatic) { log.WriteLine("メソッド '{0}' は static でない為 Benchmark を実行出来ません。", minfo); return(null); } if (minfo.GetParameters().Length != 0) { log.WriteLine("メソッド '{0}' の呼び出しには引数が必要なので Benchmark を実行出来ません。", minfo); return(null); } return(attr); }
public BenchMethod(Ref::MethodInfo minfo, BenchMethodAttribute attr) { this.minfo = minfo; this.attr = attr; Emit::DynamicMethod m = new Emit::DynamicMethod( "bench", typeof(TimeSpan), new System.Type[] { typeof(int) }, minfo.DeclaringType ); // // 宣言 // Emit::ILGenerator ilgen = m.GetILGenerator(); System.Type type_dt = typeof(System.DateTime); Emit::LocalBuilder loc_start = ilgen.DeclareLocal(type_dt); Emit::LocalBuilder loc_end = ilgen.DeclareLocal(type_dt); Emit::LocalBuilder loc_i = ilgen.DeclareLocal(typeof(int)); Ref::MethodInfo m_get_Now = type_dt.GetMethod("get_Now"); Ref::MethodInfo m_op_Subtraction = type_dt.GetMethod("op_Subtraction", new System.Type[] { type_dt, type_dt }); Emit::Label label_loopC = ilgen.DefineLabel(); Emit::Label label_loopJ = ilgen.DefineLabel(); // // ロジック // //-- pro ilgen.Emit(Emit::OpCodes.Call, m_get_Now); ilgen.Emit(Emit::OpCodes.Stloc, loc_start); //-- loop ilgen.Emit(Emit::OpCodes.Ldc_I4_0); ilgen.Emit(Emit::OpCodes.Dup); // ilgen.Emit(Emit::OpCodes.Stloc, loc_i); ilgen.Emit(Emit::OpCodes.Br_S, label_loopJ); ilgen.MarkLabel(label_loopC); ilgen.Emit(Emit::OpCodes.Call, minfo); if (minfo.ReturnType != typeof(void)) { ilgen.Emit(Emit::OpCodes.Pop); } ilgen.Emit(Emit::OpCodes.Ldloc, loc_i); ilgen.Emit(Emit::OpCodes.Ldc_I4_1); ilgen.Emit(Emit::OpCodes.Add); ilgen.Emit(Emit::OpCodes.Dup); // ilgen.Emit(Emit::OpCodes.Stloc, loc_i); ilgen.MarkLabel(label_loopJ); //ilgen.Emit(Emit::OpCodes.Ldloc,loc_i); ilgen.Emit(Emit::OpCodes.Ldarg_0); ilgen.Emit(Emit::OpCodes.Blt_S, label_loopC); //-- epi ilgen.Emit(Emit::OpCodes.Call, m_get_Now); ilgen.Emit(Emit::OpCodes.Stloc, loc_end); ilgen.Emit(Emit::OpCodes.Ldloc, loc_end); ilgen.Emit(Emit::OpCodes.Ldloc, loc_start); ilgen.Emit(Emit::OpCodes.Call, m_op_Subtraction); ilgen.Emit(Emit::OpCodes.Ret); this.meth = (MeasureTime)m.CreateDelegate(typeof(MeasureTime)); }
/// <summary> /// メソッド呼出を出力します。 /// </summary> /// <param name="minfo">呼び出すメソッドを指定します。</param> public void EmitCall(Ref::MethodInfo minfo) { gen.Emit(Emit::OpCodes.Call, minfo); }