Skip to content

Commit c7dfac0

Browse files
author
g.ph
committed
j;pdate
1 parent 15b3160 commit c7dfac0

File tree

8 files changed

+295
-72
lines changed

8 files changed

+295
-72
lines changed

PyFunc.go renamed to Py.go

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,34 @@
11
package py3
22

33
import (
4+
"fmt"
45
"github.com/aadog/py3-go/cpy3"
56
"sync"
67
)
78

89
var SystemModuleMap = sync.Map{}
10+
var GoModule *PyModule
911

12+
func InitGoModuleName(name string, doc string) {
13+
PyImport_AppendInittab(name, func() *PyObject {
14+
GoModule = CreateModule(name, doc)
15+
cls := CreateClass("MyClass", "")
16+
cls.AddFunction("z", func(self *PyObject) {
17+
fmt.Println("z")
18+
})
19+
GoModule.AddClass(cls)
20+
21+
return GoModule.AsObj()
22+
})
23+
}
1024
func Initialize() {
25+
//init python3
1126
cpy3.Py_Initialize()
12-
_UserException=PyErr_NewException("gofunction.error",PyNil,PyNil)
13-
}
14-
func AddModuleToSystemMap(m *PyModule) {
15-
SystemModuleMap.Store(m.GetName(), m)
27+
28+
//new userexception
29+
_UserException = PyErr_NewException("gofunction.error", PyNil, PyNil)
1630
}
31+
1732
func IsInitialized() int {
1833
return cpy3.Py_IsInitialized()
1934
}
@@ -35,3 +50,9 @@ func FinalizeEx() int {
3550
})
3651
return cpy3.Py_FinalizeEx()
3752
}
53+
func SetProgramName(name string) {
54+
cpy3.Py_SetProgramName(name)
55+
}
56+
func SetPythonHome(home string) {
57+
cpy3.Py_SetPythonHome(home)
58+
}

PyClass.go

Lines changed: 155 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,29 @@ package py3
33
import (
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+
}
1016
type PyClass struct {
1117
PyObject
18+
GoObj *PyClassGoObj
1219
}
1320

1421
func (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
}
2843
func 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+
//}

PyImport.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ func PyImport_Import(name string) *PyModule {
99
}
1010

1111
func PyImport_AppendInittab(name string, initFunc func() *PyObject) int {
12-
r := cpy3.PyImport_AppendInittab(name, NewModuleInitFuncCallBack(name, initFunc))
12+
r := cpy3.PyImport_AppendInittab(name, NewModuleInitFuncCallBack(name, func() *PyObject {
13+
obj := initFunc()
14+
return obj
15+
}))
1316
return r
1417
}

0 commit comments

Comments
 (0)