public MethodWrapper(Type type, string name) { // Turn the managed method into a function pointer IntPtr fp = Interop.GetThunk(type.GetMethod(name)); // XXX - here we create a Python string object, then take the // char * of the internal string to pass to our methoddef // structure. Its a hack, and the name is leaked! #if (PYTHON32 || PYTHON33 || PYTHON34) IntPtr ps = Runtime.PyBytes_FromString(name); IntPtr sp = Runtime.PyBytes_AS_STRING(ps); #else IntPtr ps = Runtime.PyString_FromString(name); IntPtr sp = Runtime.PyString_AS_STRING(ps); #endif // Allocate and initialize a PyMethodDef structure to represent // the managed method, then create a PyCFunction. mdef = Runtime.PyMem_Malloc(4 * IntPtr.Size); Marshal.WriteIntPtr(mdef, sp); Marshal.WriteIntPtr(mdef, (1 * IntPtr.Size), fp); Marshal.WriteIntPtr(mdef, (2 * IntPtr.Size), (IntPtr)0x0003); // METH_VARARGS | METH_KEYWORDS Marshal.WriteIntPtr(mdef, (3 * IntPtr.Size), IntPtr.Zero); ptr = Runtime.PyCFunction_New(mdef, IntPtr.Zero); }
//==================================================================== // Utility method to allocate a type object & do basic initialization. //==================================================================== internal static IntPtr AllocateTypeObject(string name) { IntPtr type = Runtime.PyType_GenericAlloc(Runtime.PyTypeType, 0); // Cheat a little: we'll set tp_name to the internal char * of // the Python version of the type name - otherwise we'd have to // allocate the tp_name and would have no way to free it. #if (PYTHON32 || PYTHON33 || PYTHON34 || PYTHON35) // For python3 we leak two objects. One for the ascii representation // required for tp_name, and another for the unicode representation // for ht_name. IntPtr temp = Runtime.PyBytes_FromString(name); IntPtr raw = Runtime.PyBytes_AS_STRING(temp); temp = Runtime.PyUnicode_FromString(name); #else IntPtr temp = Runtime.PyString_FromString(name); IntPtr raw = Runtime.PyString_AS_STRING(temp); #endif Marshal.WriteIntPtr(type, TypeOffset.tp_name, raw); Marshal.WriteIntPtr(type, TypeOffset.name, temp); #if (PYTHON33 || PYTHON34 || PYTHON35) Marshal.WriteIntPtr(type, TypeOffset.qualname, temp); #endif long ptr = type.ToInt64(); // 64-bit safe temp = new IntPtr(ptr + TypeOffset.nb_add); Marshal.WriteIntPtr(type, TypeOffset.tp_as_number, temp); temp = new IntPtr(ptr + TypeOffset.sq_length); Marshal.WriteIntPtr(type, TypeOffset.tp_as_sequence, temp); temp = new IntPtr(ptr + TypeOffset.mp_length); Marshal.WriteIntPtr(type, TypeOffset.tp_as_mapping, temp); #if (PYTHON32 || PYTHON33 || PYTHON34 || PYTHON35) temp = new IntPtr(ptr + TypeOffset.bf_getbuffer); Marshal.WriteIntPtr(type, TypeOffset.tp_as_buffer, temp); #else temp = new IntPtr(ptr + TypeOffset.bf_getreadbuffer); Marshal.WriteIntPtr(type, TypeOffset.tp_as_buffer, temp); #endif return(type); }