protected MethodInfo GrabPInvokeImpl(MethodInfo Original, TypeBuilder On) { if (On == null) { On = GrabType(Original.DeclaringType) as TypeBuilder; } DllImportAttribute Attr = FindCustomAttribute <DllImportAttribute>(Original); if (Attr == null) { throw new InvalidOperationException("P/Invoke method without a DllImportAttribute"); } Type ReturnType = GrabType(Original.ReturnType); Type[] Parameters = ParameterTypes(Original); if (MethodsDone.ContainsKey(Original)) { return(MethodsDone[Original]); } MethodBuilder PInvoke = On.DefinePInvokeMethod(Original.Name, Attr.Value, Original.Attributes, Original.CallingConvention, ReturnType, Parameters, Attr.CallingConvention, Attr.CharSet); PInvoke.SetImplementationFlags(Original.GetMethodImplementationFlags()); MethodsDone.Add(Original, PInvoke); return(PInvoke); }
protected MethodInfo GrabMethod(MethodInfo Original, TypeBuilder On) { if(Original == null) return null; if(MethodsDone.ContainsKey(Original)) return MethodsDone[Original]; if(!Sources.Contains(Original.Module)) return MethodReplaceGenerics(Original); if(On == null) On = GrabType(Original.DeclaringType) as TypeBuilder; if((Original.Attributes & MethodAttributes.PinvokeImpl) == MethodAttributes.PinvokeImpl) return GrabPInvokeImpl(Original, On); Type ReturnType = GrabType(Original.ReturnType); Type[] Parameters = ParameterTypes(Original); if(MethodsDone.ContainsKey(Original)) return MethodsDone[Original]; MethodBuilder Builder = On.DefineMethod(Original.Name, Original.Attributes, ReturnType, Parameters); MethodsDone.Add(Original, Builder); // Explicit interface implementations require specifying which method is being overridden. if(Original.IsFinal) { if(Original.Name.Contains(".")) { MethodInfo Overriding = FindBaseMethod(Original, Original.DeclaringType); if(Overriding != null) On.DefineMethodOverride(Builder, Overriding); } else { // Crawl among the interfaces attempting to guess the method that is being overridden. foreach(Type T in Original.DeclaringType.GetInterfaces()) { foreach(MethodInfo M in T.GetMethods()) { if(M.IsAbstract && M.Name == Original.Name) { On.DefineMethodOverride(Builder, M); goto foundoverride; // For lack of "break 2" statement. } } } } } foundoverride: Builder.SetImplementationFlags(Original.GetMethodImplementationFlags()); CopyMethodBody(Original, Builder); return Builder; }