diff --git a/src/runtime/interop.cs b/src/runtime/interop.cs index 10b6ee476..ff9a98622 100644 --- a/src/runtime/interop.cs +++ b/src/runtime/interop.cs @@ -491,6 +491,9 @@ internal static Type GetPrototype(string name) return pmap[name] as Type; } + + internal static Dictionary allocatedThunks = new Dictionary(); + internal static ThunkInfo GetThunk(MethodInfo method, string funcType = null) { Type dt; @@ -505,6 +508,7 @@ internal static ThunkInfo GetThunk(MethodInfo method, string funcType = null) } Delegate d = Delegate.CreateDelegate(dt, method); var info = new ThunkInfo(d); + allocatedThunks[info.Address] = d; return info; } diff --git a/src/runtime/managedtype.cs b/src/runtime/managedtype.cs index 87a89b00a..b4baef835 100644 --- a/src/runtime/managedtype.cs +++ b/src/runtime/managedtype.cs @@ -178,7 +178,7 @@ internal static int PyVisit(IntPtr ob, IntPtr visit, IntPtr arg) { return 0; } - var visitFunc = (Interop.ObjObjFunc)Marshal.GetDelegateForFunctionPointer(visit, typeof(Interop.ObjObjFunc)); + var visitFunc = NativeCall.GetDelegate(visit); return visitFunc(ob, arg); } @@ -196,7 +196,7 @@ internal void CallTypeClear() { return; } - var clearFunc = (Interop.InquiryFunc)Marshal.GetDelegateForFunctionPointer(clearPtr, typeof(Interop.InquiryFunc)); + var clearFunc = NativeCall.GetDelegate(clearPtr); clearFunc(pyHandle); } @@ -214,7 +214,8 @@ internal void CallTypeTraverse(Interop.ObjObjFunc visitproc, IntPtr arg) { return; } - var traverseFunc = (Interop.ObjObjArgFunc)Marshal.GetDelegateForFunctionPointer(traversePtr, typeof(Interop.ObjObjArgFunc)); + var traverseFunc = NativeCall.GetDelegate(traversePtr); + var visiPtr = Marshal.GetFunctionPointerForDelegate(visitproc); traverseFunc(pyHandle, visiPtr, arg); } diff --git a/src/runtime/nativecall.cs b/src/runtime/nativecall.cs index e33eb1c81..60259dcd0 100644 --- a/src/runtime/nativecall.cs +++ b/src/runtime/nativecall.cs @@ -40,10 +40,15 @@ public static int Int_Call_3(IntPtr fp, IntPtr a1, IntPtr a2, IntPtr a3) return d(a1, a2, a3); } - private static T GetDelegate(IntPtr fp) where T: Delegate + internal static T GetDelegate(IntPtr fp) where T: Delegate { - // Use Marshal.GetDelegateForFunctionPointer<> directly after upgrade the framework - return (T)Marshal.GetDelegateForFunctionPointer(fp, typeof(T)); + Delegate d = null; + if (!Interop.allocatedThunks.TryGetValue(fp, out d)) + { + // We don't cache this delegate because this is a pure delegate ot unmanaged. + d = Marshal.GetDelegateForFunctionPointer(fp); + } + return (T)d; } } }