public PyModule(string name, IDictionary <string, PyCFunction> funcs) { _functions = new Dictionary <string, PyCFunction>(funcs); var methodDefs = new List <PyMethodDef>(); foreach (var func in _functions) { var methodDef = new PyMethodDef(); methodDef.ml_name = Marshal.StringToHGlobalAnsi(func.Key); methodDef.ml_doc = IntPtr.Zero; methodDef.ml_flags = METH_VARARGS; methodDef.ml_meth = Marshal.GetFunctionPointerForDelegate(func.Value); methodDefs.Add(methodDef); } _defs = methodDefs.ToArray(); var ptrModuleDef = new IntPtr(); var modResult = create_module(name, _defs, _defs.Length, out ptrModuleDef); _module = new PyObject(modResult); }
GenerateCallablesFromMethodDefs(StringBuilder code, IntPtr methods, PythonDictionary methodTable, string tablePrefix, string oldargsTemplate, string noargsTemplate, string objargTemplate, string varargsTemplate, string varargsKwargsTemplate) { IntPtr methodPtr = methods; if (methodPtr == IntPtr.Zero) { return; } while (CPyMarshal.ReadInt(methodPtr) != 0) { PyMethodDef thisMethod = (PyMethodDef)Marshal.PtrToStructure( methodPtr, typeof(PyMethodDef)); string name = thisMethod.ml_name; string template = null; Delegate dgt = null; // COEXIST flag ignored; which method is chosen depends on order of calls in ClassBuilder. bool unsupportedFlags = false; METH flags = (METH)thisMethod.ml_flags & ~METH.COEXIST; switch (flags) { case METH.OLDARGS: template = oldargsTemplate; dgt = Marshal.GetDelegateForFunctionPointer( thisMethod.ml_meth, typeof(dgt_ptr_ptrptr)); break; case METH.NOARGS: template = noargsTemplate; dgt = Marshal.GetDelegateForFunctionPointer( thisMethod.ml_meth, typeof(dgt_ptr_ptrptr)); break; case METH.O: template = objargTemplate; dgt = Marshal.GetDelegateForFunctionPointer( thisMethod.ml_meth, typeof(dgt_ptr_ptrptr)); break; case METH.VARARGS: template = varargsTemplate; dgt = Marshal.GetDelegateForFunctionPointer( thisMethod.ml_meth, typeof(dgt_ptr_ptrptr)); break; case METH.KEYWORDS: case METH.VARARGS | METH.KEYWORDS: template = varargsKwargsTemplate; dgt = Marshal.GetDelegateForFunctionPointer( thisMethod.ml_meth, typeof(dgt_ptr_ptrptrptr)); break; default: unsupportedFlags = true; break; } if (!unsupportedFlags) { code.Append(String.Format(template, name, thisMethod.ml_doc, tablePrefix)); methodTable[tablePrefix + name] = dgt; } else { Console.WriteLine("Detected unsupported method flags for {0}{1} ({2}); ignoring.", tablePrefix, name, thisMethod.ml_flags); } methodPtr = CPyMarshal.Offset(methodPtr, Marshal.SizeOf(typeof(PyMethodDef))); } }
public static extern IntPtr PyCFunction_New(ref PyMethodDef ml, IntPtr self);