44using System . Runtime . InteropServices ;
55using System . Reflection ;
66using System . Text ;
7+ using System . Collections . Generic ;
78
89namespace Python . Runtime
910{
@@ -334,7 +335,7 @@ internal class TypeFlags
334335
335336 internal class Interop
336337 {
337- private static ArrayList keepAlive ;
338+ private static List < ThunkInfo > keepAlive ;
338339 private static Hashtable pmap ;
339340
340341 static Interop ( )
@@ -351,8 +352,7 @@ static Interop()
351352 p [ item . Name ] = item ;
352353 }
353354
354- keepAlive = new ArrayList ( ) ;
355- Marshal . AllocHGlobal ( IntPtr . Size ) ;
355+ keepAlive = new List < ThunkInfo > ( ) ;
356356 pmap = new Hashtable ( ) ;
357357
358358 pmap [ "tp_dealloc" ] = p [ "DestructorFunc" ] ;
@@ -449,26 +449,23 @@ internal static Type GetPrototype(string name)
449449 return pmap [ name ] as Type ;
450450 }
451451
452- internal static IntPtr GetThunk ( MethodInfo method , string funcType = null )
452+ internal static ThunkInfo GetThunk ( MethodInfo method , string funcType = null )
453453 {
454454 Type dt ;
455455 if ( funcType != null )
456456 dt = typeof ( Interop ) . GetNestedType ( funcType ) as Type ;
457457 else
458458 dt = GetPrototype ( method . Name ) ;
459459
460- if ( dt ! = null )
460+ if ( dt = = null )
461461 {
462- IntPtr tmp = Marshal . AllocHGlobal ( IntPtr . Size ) ;
463- Delegate d = Delegate . CreateDelegate ( dt , method ) ;
464- Thunk cb = new Thunk ( d ) ;
465- Marshal . StructureToPtr ( cb , tmp , false ) ;
466- IntPtr fp = Marshal . ReadIntPtr ( tmp , 0 ) ;
467- Marshal . FreeHGlobal ( tmp ) ;
468- keepAlive . Add ( d ) ;
469- return fp ;
462+ return ThunkInfo . Empty ;
470463 }
471- return IntPtr . Zero ;
464+ Delegate d = Delegate . CreateDelegate ( dt , method ) ;
465+ var info = new ThunkInfo ( d ) ;
466+ // TODO: remove keepAlive when #958 merged, let the lifecycle of ThunkInfo transfer to caller.
467+ keepAlive . Add ( info ) ;
468+ return info ;
472469 }
473470
474471 [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
@@ -522,4 +519,22 @@ public Thunk(Delegate d)
522519 fn = d ;
523520 }
524521 }
522+
523+ internal class ThunkInfo
524+ {
525+ public readonly Delegate Target ;
526+ public readonly IntPtr Address ;
527+
528+ public static readonly ThunkInfo Empty = new ThunkInfo ( null ) ;
529+
530+ public ThunkInfo ( Delegate target )
531+ {
532+ if ( target == null )
533+ {
534+ return ;
535+ }
536+ Target = target ;
537+ Address = Marshal . GetFunctionPointerForDelegate ( target ) ;
538+ }
539+ }
525540}
0 commit comments