func (self PythonPlugin) Run(content string) (types.ValueMap, error) { var ccontent = C.CString(content) var cerror *C.char var cvalues *C.valuelist_t defer C.free(unsafe.Pointer(ccontent)) if C.run_python(ccontent, &cerror, &cvalues) < 0 { return nil, errors.New(C.GoString(cerror)) } defer C.free_valuelist(cvalues) valuemap := types.NewValueMap() names := uintptr(unsafe.Pointer(cvalues.names)) values := uintptr(unsafe.Pointer(cvalues.values)) var cname *C.char var name string var cvalue *C.PyObject for i := uintptr(0); i < uintptr(cvalues.numitems); i++ { offset := i * unsafe.Sizeof(i) cname = *(**C.char)(unsafe.Pointer(names + offset)) cvalue = *(**C.PyObject)(unsafe.Pointer(values + offset)) name = C.GoString(cname) valuemap.Assign(name, PythonCallable{name: name, callable: cvalue}) } return valuemap, nil }
func (self *Python) run_python(py_name string) (*PyObject, error) { if len(strings.Trim(py_name, "")) < 1 { return nil, fmt.Errorf("`py_name` is empty.") } _p := strings.Split(py_name, ":") if len(_p) != 2 { return nil, fmt.Errorf("`py_name` must be `<module>:<function>`.") } _module_name, _function_name := _p[0], _p[1] log.Debug("`%s.%s(...)` will be called.", _module_name, _function_name) runtime.LockOSThread() defer runtime.UnlockOSThread() _result := new(C.PyObject) _tid := self.threadpool.Start( ThreadCallback(func(args unsafe.Pointer) { _gstate := C.thread_begin() defer C.thread_end(_gstate) _result = C.run_python( C.CString(_module_name), C.CString(_function_name), ) log.Debug("in callback: %s, result: %v", py_name, _result) }), ) self.threadpool.Join(_tid) return &PyObject{Ptr: _result}, nil }