@@ -267,6 +267,28 @@ internal static IntPtr CreateSubType(IntPtr py_name, IntPtr py_base_type, IntPtr
267267 }
268268 }
269269
270+ internal static IntPtr WriteMethodDef ( IntPtr mdef , IntPtr name , IntPtr func , int flags , IntPtr doc )
271+ {
272+ Marshal . WriteIntPtr ( mdef , name ) ;
273+ Marshal . WriteIntPtr ( mdef , ( 1 * IntPtr . Size ) , func ) ;
274+ Marshal . WriteInt32 ( mdef , ( 2 * IntPtr . Size ) , flags ) ;
275+ Marshal . WriteIntPtr ( mdef , ( 3 * IntPtr . Size ) , doc ) ;
276+ return mdef + 4 * IntPtr . Size ;
277+ }
278+
279+ internal static IntPtr WriteMethodDef ( IntPtr mdef , string name , IntPtr func , int flags = 0x0001 , string doc = null )
280+ {
281+ IntPtr namePtr = Marshal . StringToHGlobalAnsi ( name ) ;
282+ IntPtr docPtr = doc != null ? Marshal . StringToHGlobalAnsi ( doc ) : IntPtr . Zero ;
283+
284+ return WriteMethodDef ( mdef , namePtr , func , flags , docPtr ) ;
285+ }
286+
287+ internal static IntPtr WriteMethodDefSentinel ( IntPtr mdef )
288+ {
289+ return WriteMethodDef ( mdef , IntPtr . Zero , IntPtr . Zero , 0 , IntPtr . Zero ) ;
290+ }
291+
270292 internal static IntPtr CreateMetaType ( Type impl ) {
271293
272294 // The managed metatype is functionally little different than the
@@ -302,20 +324,25 @@ internal static IntPtr CreateMetaType(Type impl) {
302324 flags |= TypeFlags . HaveGC ;
303325 Marshal . WriteIntPtr ( type , TypeOffset . tp_flags , ( IntPtr ) flags ) ;
304326
305- IntPtr fp = Interop . GetThunk ( typeof ( MetaType ) . GetMethod ( "__instancecheck__" ) ) ;
306- IntPtr mdef = Runtime . PyMem_Malloc ( 5 * IntPtr . Size ) ;
307- Marshal . WriteIntPtr ( mdef , Marshal . StringToHGlobalAnsi ( "__instancecheck__" ) ) ;
308- Marshal . WriteIntPtr ( mdef , ( 1 * IntPtr . Size ) , fp ) ;
309- Marshal . WriteInt32 ( mdef , ( 2 * IntPtr . Size ) , 0x0001 ) ;
310- Marshal . WriteIntPtr ( mdef , ( 3 * IntPtr . Size ) , IntPtr . Zero ) ;
311-
312- // Write empty sentinel struct
313- Marshal . WriteIntPtr ( mdef , ( 4 * IntPtr . Size ) , IntPtr . Zero ) ;
314- Marshal . WriteIntPtr ( mdef , ( 5 * IntPtr . Size ) , IntPtr . Zero ) ;
315- Marshal . WriteIntPtr ( mdef , ( 6 * IntPtr . Size ) , IntPtr . Zero ) ;
316- Marshal . WriteIntPtr ( mdef , ( 7 * IntPtr . Size ) , IntPtr . Zero ) ;
317-
318- Marshal . WriteIntPtr ( type , TypeOffset . tp_methods , mdef ) ;
327+ // We need space for 3 PyMethodDef structs, each of them
328+ // 4 int-ptrs in size.
329+ IntPtr mdef = Runtime . PyMem_Malloc ( 3 * ( 4 * IntPtr . Size ) ) ;
330+ IntPtr mdefStart = mdef ;
331+ mdef = WriteMethodDef (
332+ mdef ,
333+ "__instancecheck__" ,
334+ Interop . GetThunk ( typeof ( MetaType ) . GetMethod ( "__instancecheck__" ) , "BinaryFunc" )
335+ ) ;
336+
337+ mdef = WriteMethodDef (
338+ mdef ,
339+ "__subclasscheck__" ,
340+ Interop . GetThunk ( typeof ( MetaType ) . GetMethod ( "__subclasscheck__" ) , "BinaryFunc" )
341+ ) ;
342+
343+ mdef = WriteMethodDefSentinel ( mdef ) ;
344+
345+ Marshal . WriteIntPtr ( type , TypeOffset . tp_methods , mdefStart ) ;
319346
320347 Runtime . PyType_Ready ( type ) ;
321348
0 commit comments