@@ -3,18 +3,29 @@ package py3
33import (
44 "fmt"
55 "github.com/aadog/py3-go/cpy3"
6+ "sync"
67 "syscall"
78 "unsafe"
89)
910
11+ var SystemClassMap = sync.Map {}
12+
13+ type PyClassGoObj struct {
14+ CallMap sync.Map
15+ }
1016type PyClass struct {
1117 PyObject
18+ GoObj * PyClassGoObj
1219}
1320
1421func (p * PyClass ) GetName () string {
1522 return p .GetAttrString ("__className__" ).AsUTF8 ()
1623}
1724
25+ func (p * PyClass ) AddFunction (name string , fn interface {}) {
26+ p .GoObj .CallMap .Store (name , fn )
27+ }
28+
1829// PyClassFromInst
1930// 新建一个对象来自已经存在的对象实例指针。
2031//
@@ -23,44 +34,167 @@ func PyClassFromInst(inst uintptr) *PyClass {
2334 dl := new (PyClass )
2435 dl .instance = inst
2536 dl .ptr = unsafe .Pointer (dl .instance )
37+
38+ name := dl .GetName ()
39+ smmodule , _ := SystemClassMap .Load (name )
40+ dl .GoObj = smmodule .(* PyClass ).GoObj
2641 return dl
2742}
2843func PyClassFromObj (obj * PyObject ) * PyClass {
2944 dl := new (PyClass )
3045 dl .PyObject = * obj
46+
47+ name := dl .GetName ()
48+ smmodule , _ := SystemClassMap .Load (name )
49+ dl .GoObj = smmodule .(* PyClass ).GoObj
3150 return dl
3251}
3352
34- func CreateClass (name string , dict map [string ]any ) * PyClass {
35- if dict == nil {
36- dict = map [string ]any {}
37- }
53+ func PyClassInstanceMethodForward (self * PyObject , args * PyTuple , method interface {}) * PyObject {
54+ fmt .Println ("class call" )
55+ // methodType := reflect.TypeOf(method)
56+ // methodValue := reflect.ValueOf(method)
57+ // if methodType.Kind() != reflect.Func {
58+ // return Py_RETURN_NONE().AsObj()
59+ // }
60+ // if int64(methodType.NumIn()) != args.Size() {
61+ // PyErr_SetString(UserException(), fmt.Sprintf("The number of parameters does not match,%d parameter is required, and you have entered %d", methodType.NumIn(), args.Size()))
62+ // return Py_RETURN_NONE().AsObj()
63+ // }
64+ //
65+ // fnArgs := make([]reflect.Value, 0)
66+ // for i := 0; i < methodType.NumIn(); i++ {
67+ // fnArgType := methodType.In(i)
68+ // inArg := args.GetItem(int64(i))
69+ // fnArgs = append(fnArgs, reflect.ValueOf(PyObjectToGo(inArg, fnArgType)))
70+ // }
71+ // rets := methodValue.Call(fnArgs)
72+ // if len(rets) == 1 {
73+ // firstRet := rets[0]
74+ // r := GoToPyObject(firstRet.Interface())
75+ // return r
76+ // } else if len(rets) > 1 {
77+ // l := NewPyList(0)
78+ // for _, r := range rets {
79+ // obj := GoToPyObject(r.Interface())
80+ // defer obj.DecRef()
81+ // l.Append(obj)
82+ // }
83+ // return l.AsObj()
84+ // }
85+ return Py_RETURN_NONE ().AsObj ()
86+ }
87+
88+ func CreateClass (name string , doc string ) * PyClass {
89+ class := & PyClass {}
90+ class .GoObj = new (PyClassGoObj )
91+
92+ dict := map [string ]any {}
3893 pClassName := GoToPyObject (name )
3994 defer pClassName .DecRef ()
4095 pClassBases := NewPyTuple (0 )
4196 defer pClassBases .DecRef ()
4297 pClassDic := GoToPyObject (dict )
4398 defer pClassDic .DecRef ()
44- pClass := PyObjectFromInst (cpy3 .PyObject_CallFunctionObjArgs (cpy3 .PyType_Type (), pClassName .Instance (), pClassBases .Instance (), pClassDic .Instance (), 0 ))
45- pClass .SetAttrString ("__className__" , NewPyUnicode (name ).AsObj ())
99+ class .instance = cpy3 .PyObject_CallFunctionObjArgs (cpy3 .PyType_Type (), pClassName .Instance (), pClassBases .Instance (), pClassDic .Instance (), 0 )
100+ class .ptr = unsafe .Pointer (class .instance )
101+ class .SetAttrString ("__className__" , pClassName )
102+
103+ fn := PyObjectFromInst (cpy3 .PyCFunction_New (uintptr (unsafe .Pointer (PyClassInstanceMethodCallDef )), PyNil .instance ))
104+ defer fn .DecRef ()
105+ method := PyObjectFromInst (cpy3 .PyInstanceMethod (fn .instance ))
106+ defer method .DecRef ()
107+ class .SetAttrString ("Call" , method )
46108
47- fnName := "Call"
48- methodCallDef := & cpy3.PyMethodDef {
49- Ml_name : cpy3 .GoStrToCStr (fnName ),
50- Ml_meth : syscall .NewCallback (func () uintptr {
51- fmt .Println ("call" )
109+ SystemClassMap .Store (name , class )
110+ return class
111+ }
52112
113+ var PyClassInstanceMethodCallDef * cpy3.PyMethodDef
114+ var PyClassInstanceMethodForwardCallBack = syscall .NewCallback (func (self uintptr , args uintptr ) uintptr {
115+ pyArgs := PyTupleFromInst (args )
116+ arg1 := pyArgs .GetItem (0 )
117+ tp := arg1 .Type ()
118+ defer tp .DecRef ()
119+ if tp .Name () == "str" {
120+ fmt .Println ("static" )
121+ } else {
122+ pyArgsLen := pyArgs .Size ()
123+ if pyArgsLen < 2 {
53124 return Py_RETURN_NONE ().instance
54- }),
55- Ml_flags : 0 ,
56- Ml_doc : cpy3 .GoStrToCStr ("module call forward" ),
125+ }
126+ ForwardCode := pyArgs .GetItem (1 ).Str ()
127+
128+ //处理参数
129+ newArgs := PyTupleFromObj (pyArgs .GetSlice (2 , pyArgsLen ))
130+ defer newArgs .DecRef ()
131+ pySelf := pyArgs .GetItem (0 )
132+
133+ PyClass := PyClassFromObj (pySelf )
134+ className := PyClass .GetName ()
135+ ifn , ok := PyClass .GoObj .CallMap .Load (ForwardCode )
136+ if ok == false {
137+ PyErr_SetString (UserException (), fmt .Sprintf ("%s not find method %s " , className , ForwardCode ))
138+ return Py_RETURN_NONE ().Instance ()
139+ }
140+
141+ return PyClassInstanceMethodForward (pySelf , newArgs , ifn ).instance
57142 }
58- PyMethodMap .Store ("x" , methodCallDef )
143+ return Py_RETURN_NONE ().instance
144+ })
59145
60- fn := PyObjectFromInst (cpy3 .PyCFunction_New (uintptr (unsafe .Pointer (methodCallDef )), cpy3 .PyTuple_New (0 )))
61- defer fn .DecRef ()
62- method := PyObjectFromInst (cpy3 .PyInstanceMethod (fn .instance ))
63- defer method .DecRef ()
64- pClass .SetAttrString (fnName , method )
65- return PyClassFromObj (pClass )
146+ func init () {
147+ PyClassInstanceMethodCallDef = & cpy3.PyMethodDef {
148+ Ml_name : cpy3 .GoStrToCStr ("Call" ),
149+ Ml_meth : PyClassInstanceMethodForwardCallBack ,
150+ Ml_flags : 3 ,
151+ Ml_doc : cpy3 .GoStrToCStr ("class call forward" ),
152+ }
66153}
154+
155+ //func CreateClass(name string, dict map[string]any) *PyClass {
156+ // if dict == nil {
157+ // dict = map[string]any{}
158+ // }
159+ // pClassName := GoToPyObject(name)
160+ // defer pClassName.DecRef()
161+ // pClassBases := NewPyTuple(0)
162+ // defer pClassBases.DecRef()
163+ // pClassDic := GoToPyObject(dict)
164+ // defer pClassDic.DecRef()
165+ // pClass := PyObjectFromInst(cpy3.PyObject_CallFunctionObjArgs(cpy3.PyType_Type(), pClassName.Instance(), pClassBases.Instance(), pClassDic.Instance(), 0))
166+ // pClass.SetAttrString("__className__", NewPyUnicode(name).AsObj())
167+ //
168+ // fnName := "Call"
169+ // methodCallDef := &cpy3.PyMethodDef{
170+ // Ml_name: cpy3.GoStrToCStr(fnName),
171+ // Ml_meth: syscall.NewCallback(func(self uintptr, args uintptr) uintptr {
172+ // pyArgs := PyTupleFromInst(args)
173+ // pyArgsLen := pyArgs.Size()
174+ // if pyArgsLen < 2 {
175+ // return Py_RETURN_NONE().instance
176+ // }
177+ // pySelf := pyArgs.GetItem(0)
178+ // ForwardCode := pyArgs.GetItem(1).Str()
179+ //
180+ // ifn, ok := PyMethodMap.Load(ForwardCode)
181+ // if ok == false {
182+ // return Py_RETURN_NONE().Instance()
183+ // }
184+ // //处理参数
185+ // newArgs := PyTupleFromObj(pyArgs.GetSlice(1, pyArgsLen))
186+ // defer newArgs.DecRef()
187+ // return PyInstanceMethodForward(pySelf, newArgs, ifn).Instance()
188+ // }),
189+ // Ml_flags: 3,
190+ // Ml_doc: cpy3.GoStrToCStr("module call forward"),
191+ // }
192+ // PyMethodMap.Store("x", methodCallDef)
193+ //
194+ // fn := PyObjectFromInst(cpy3.PyCFunction_New(uintptr(unsafe.Pointer(methodCallDef)), PyNil.instance))
195+ // defer fn.DecRef()
196+ // method := PyObjectFromInst(cpy3.PyInstanceMethod(fn.instance))
197+ // defer method.DecRef()
198+ // pClass.SetAttrString(fnName, method)
199+ // return PyClassFromObj(pClass)
200+ //}
0 commit comments