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

Skip to content

Commit 9307bb3

Browse files
authored
Fix illegal delegate usage (#1328)
* 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.) * Use the generic method
1 parent 139dc87 commit 9307bb3

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+
// We don't cache this delegate because this is a pure delegate ot unmanaged.
49+
d = Marshal.GetDelegateForFunctionPointer<T>(fp);
50+
}
51+
return (T)d;
4752
}
4853
}
4954
}

0 commit comments

Comments
 (0)