|
| 1 | +package py3_go |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "github.com/aadog/py3-go/cpy3" |
| 6 | + "sync" |
| 7 | + "syscall" |
| 8 | + "unsafe" |
| 9 | +) |
| 10 | + |
| 11 | +var PyMethodMap = sync.Map{} |
| 12 | +var pyModuleInitMap = sync.Map{} |
| 13 | +var PyMethodCallBack = syscall.NewCallback(func(self uintptr, args uintptr) uintptr { |
| 14 | + pyArgs := PyTupleFromInst(args) |
| 15 | + pyArgsLen := pyArgs.Size() |
| 16 | + if pyArgsLen < 1 { |
| 17 | + return Py_RETURN_NONE().instance |
| 18 | + } |
| 19 | + code := pyArgs.GetItem(0) |
| 20 | + |
| 21 | + ifn, ok := PyMethodMap.Load(code.Str()) |
| 22 | + if ok == false { |
| 23 | + return Py_RETURN_NONE().Instance() |
| 24 | + } |
| 25 | + //处理参数 |
| 26 | + newArgs := pyArgs.GetSlice(1, pyArgsLen) |
| 27 | + defer newArgs.DecRef() |
| 28 | + fn := ifn.(func(self *PyObject, args *PyObject) *PyObject) |
| 29 | + return fn(PyObjectFromInst(self), PyObjectFromInst(newArgs.Instance())).Instance() |
| 30 | +}) |
| 31 | + |
| 32 | +type PyMethodType = func(self *PyObject, args *PyObject) *PyObject |
| 33 | + |
| 34 | +type PyModule struct { |
| 35 | + PyObject |
| 36 | +} |
| 37 | + |
| 38 | +func (p *PyModule) GetName() string { |
| 39 | + return cpy3.PyModule_GetName(p.instance) |
| 40 | +} |
| 41 | +func (p *PyModule) GetDict() *PyDict { |
| 42 | + return PyDictFromInst(cpy3.PyModule_GetDict(p.instance)) |
| 43 | +} |
| 44 | +func (p *PyModule) AddFunctions(functionsDef []PyMethodDef) int { |
| 45 | + methods := make([]cpy3.PyMethodDef, 0) |
| 46 | + moduleName := p.GetName() |
| 47 | + for _, method := range functionsDef { |
| 48 | + methodName := method.Name |
| 49 | + methods = append(methods, cpy3.PyMethodDef{ |
| 50 | + Ml_name: cpy3.GoStrToCStr(method.Name), |
| 51 | + Ml_meth: NewMethodCallBack(moduleName, methodName, method.Method), |
| 52 | + Ml_flags: method.flags, |
| 53 | + Ml_doc: cpy3.GoStrToCStr(method.Doc), |
| 54 | + }) |
| 55 | + } |
| 56 | + methods = append(methods, cpy3.PyMethodDef{ |
| 57 | + Ml_name: 0, |
| 58 | + Ml_meth: 0, |
| 59 | + Ml_flags: 0, |
| 60 | + Ml_doc: 0, |
| 61 | + }) |
| 62 | + return cpy3.PyModule_AddFunctions(p.instance, uintptr(unsafe.Pointer(&methods[0]))) |
| 63 | +} |
| 64 | +func (p *PyModule) AddIntConstant(name string, value int64) int { |
| 65 | + return cpy3.PyModule_AddIntConstant(p.instance, name, value) |
| 66 | +} |
| 67 | +func (p *PyModule) AddStringConstant(name string, value string) int { |
| 68 | + return cpy3.PyModule_AddStringConstant(p.instance, name, value) |
| 69 | +} |
| 70 | +func (p *PyModule) AddObject(name string, value *PyObject) int { |
| 71 | + return cpy3.PyModule_AddObject(p.instance, name, value.instance) |
| 72 | +} |
| 73 | +func (p *PyModule) AddObjectRef(name string, value *PyObject) int { |
| 74 | + return cpy3.PyModule_AddObjectRef(p.instance, name, value.instance) |
| 75 | +} |
| 76 | + |
| 77 | +// PyModuleFromInst |
| 78 | +// 新建一个对象来自已经存在的对象实例指针。 |
| 79 | +// |
| 80 | +// Create a new object from an existing object instance pointer. |
| 81 | +func PyModuleFromInst(inst uintptr) *PyModule { |
| 82 | + dl := new(PyModule) |
| 83 | + dl.instance = inst |
| 84 | + dl.ptr = unsafe.Pointer(dl.instance) |
| 85 | + return dl |
| 86 | +} |
| 87 | + |
| 88 | +func NewModuleInitFuncCallBack(moduleName string, fn func() *PyObject) uintptr { |
| 89 | + c := syscall.NewCallback(func() uintptr { |
| 90 | + return fn().Instance() |
| 91 | + }) |
| 92 | + pyModuleInitMap.Store(moduleName, c) |
| 93 | + return c |
| 94 | +} |
| 95 | +func NewMethodCallBack(moduleName string, methodName string, fn func(self *PyObject, args *PyObject) *PyObject) uintptr { |
| 96 | + PyMethodMap.Store(fmt.Sprintf("%s.%s", moduleName, methodName), fn) |
| 97 | + return PyMethodCallBack |
| 98 | +} |
| 99 | + |
| 100 | +func CreateModule(def *PyModuleDef) *PyObject { |
| 101 | + moduleName := def.Name |
| 102 | + methods := make([]cpy3.PyMethodDef, 0) |
| 103 | + for _, method := range def.MethodDefs { |
| 104 | + methodName := method.Name |
| 105 | + methods = append(methods, cpy3.PyMethodDef{ |
| 106 | + Ml_name: cpy3.GoStrToCStr(method.Name), |
| 107 | + Ml_meth: NewMethodCallBack(moduleName, methodName, method.Method), |
| 108 | + Ml_flags: method.flags, |
| 109 | + Ml_doc: cpy3.GoStrToCStr(method.Doc), |
| 110 | + }) |
| 111 | + } |
| 112 | + methods = append(methods, cpy3.PyMethodDef{ |
| 113 | + Ml_name: 0, |
| 114 | + Ml_meth: 0, |
| 115 | + Ml_flags: 0, |
| 116 | + Ml_doc: 0, |
| 117 | + }) |
| 118 | + |
| 119 | + moduleDef := cpy3.PyModuleDef{ |
| 120 | + M_base: cpy3.PyModuleDef_Base{ |
| 121 | + Ob_base: cpy3.PyObject_HEAD_INIT(0), |
| 122 | + }, |
| 123 | + M_name: cpy3.GoStrToCStr(def.Name), |
| 124 | + M_doc: cpy3.GoStrToCStr(def.Doc), |
| 125 | + M_size: -1, |
| 126 | + M_methods: uintptr(unsafe.Pointer(&methods[0])), |
| 127 | + M_slots: 0, |
| 128 | + M_traverse: 0, |
| 129 | + M_clear: 0, |
| 130 | + M_free: 0, |
| 131 | + } |
| 132 | + ptr := cpy3.PyModule_Create2(uintptr(unsafe.Pointer(&moduleDef)), 1013) |
| 133 | + return PyObjectFromInst(ptr) |
| 134 | +} |
0 commit comments