Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5d9f76f

Browse files
committed
Fix illegal delegate usage
Cache the delegates to native code we've created so that when we need to call that delegate, we don't ask for a delegate from a native pointer (that is a delegate to managed code.)
1 parent 44a36dc commit 5d9f76f

File tree

3 files changed

+16
-6
lines changed

3 files changed

+16
-6
lines changed

src/runtime/interop.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,9 @@ internal static Type GetPrototype(string name)
491491
return pmap[name] as Type;
492492
}
493493

494+
495+
internal static Dictionary<IntPtr, Delegate> allocatedThunks = new Dictionary<IntPtr, Delegate>();
496+
494497
internal static ThunkInfo GetThunk(MethodInfo method, string funcType = null)
495498
{
496499
Type dt;
@@ -505,6 +508,7 @@ internal static ThunkInfo GetThunk(MethodInfo method, string funcType = null)
505508
}
506509
Delegate d = Delegate.CreateDelegate(dt, method);
507510
var info = new ThunkInfo(d);
511+
allocatedThunks[info.Address] = d;
508512
return info;
509513
}
510514

src/runtime/managedtype.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ internal static int PyVisit(IntPtr ob, IntPtr visit, IntPtr arg)
178178
{
179179
return 0;
180180
}
181-
var visitFunc = (Interop.ObjObjFunc)Marshal.GetDelegateForFunctionPointer(visit, typeof(Interop.ObjObjFunc));
181+
var visitFunc = NativeCall.GetDelegate<Interop.ObjObjFunc>(visit);
182182
return visitFunc(ob, arg);
183183
}
184184

@@ -196,7 +196,7 @@ internal void CallTypeClear()
196196
{
197197
return;
198198
}
199-
var clearFunc = (Interop.InquiryFunc)Marshal.GetDelegateForFunctionPointer(clearPtr, typeof(Interop.InquiryFunc));
199+
var clearFunc = NativeCall.GetDelegate<Interop.InquiryFunc>(clearPtr);
200200
clearFunc(pyHandle);
201201
}
202202

@@ -214,7 +214,8 @@ internal void CallTypeTraverse(Interop.ObjObjFunc visitproc, IntPtr arg)
214214
{
215215
return;
216216
}
217-
var traverseFunc = (Interop.ObjObjArgFunc)Marshal.GetDelegateForFunctionPointer(traversePtr, typeof(Interop.ObjObjArgFunc));
217+
var traverseFunc = NativeCall.GetDelegate<Interop.ObjObjArgFunc>(traversePtr);
218+
218219
var visiPtr = Marshal.GetFunctionPointerForDelegate(visitproc);
219220
traverseFunc(pyHandle, visiPtr, arg);
220221
}

src/runtime/nativecall.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,15 @@ public static int Int_Call_3(IntPtr fp, IntPtr a1, IntPtr a2, IntPtr a3)
4040
return d(a1, a2, a3);
4141
}
4242

43-
private static T GetDelegate<T>(IntPtr fp) where T: Delegate
43+
internal static T GetDelegate<T>(IntPtr fp) where T: Delegate
4444
{
45-
// Use Marshal.GetDelegateForFunctionPointer<> directly after upgrade the framework
46-
return (T)Marshal.GetDelegateForFunctionPointer(fp, typeof(T));
45+
Delegate d = null;
46+
if (!Interop.allocatedThunks.TryGetValue(fp, out d))
47+
{
48+
// Use Marshal.GetDelegateForFunctionPointer<> directly after upgrade the framework
49+
d = Marshal.GetDelegateForFunctionPointer(fp, typeof(T));
50+
}
51+
return (T)d;
4752
}
4853
}
4954
}

0 commit comments

Comments
 (0)