Exemplo n.º 1
0
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
}