From 7dc80d9420cc725d800b8e14787c0a735f8744c9 Mon Sep 17 00:00:00 2001 From: fanchy Date: Tue, 22 Oct 2019 20:16:35 +0800 Subject: [PATCH 01/13] support pythonV3 --- ffpython.cpp | 608 +++ pyops_base.h | 1130 ++++++ pyops_for_embed.h | 77 + pyops_for_extend.h | 1745 ++++++++ python2.7/VersionForRead/ffpython.cpp | 568 +++ python2.7/VersionForRead/ffpython.h | 481 +++ python2.7/VersionForRead/pyops_base.h | 1123 ++++++ python2.7/VersionForRead/pyops_for_embed.h | 77 + python2.7/VersionForRead/pyops_for_extend.h | 1745 ++++++++ python2.7/ffpython.h | 3931 +++++++++++++++++++ vs2008.x86/ffpython.vcxproj | 177 + 11 files changed, 11662 insertions(+) create mode 100644 ffpython.cpp create mode 100644 pyops_base.h create mode 100644 pyops_for_embed.h create mode 100644 pyops_for_extend.h create mode 100644 python2.7/VersionForRead/ffpython.cpp create mode 100644 python2.7/VersionForRead/ffpython.h create mode 100644 python2.7/VersionForRead/pyops_base.h create mode 100644 python2.7/VersionForRead/pyops_for_embed.h create mode 100644 python2.7/VersionForRead/pyops_for_extend.h create mode 100644 python2.7/ffpython.h create mode 100644 vs2008.x86/ffpython.vcxproj diff --git a/ffpython.cpp b/ffpython.cpp new file mode 100644 index 0000000..336ae1c --- /dev/null +++ b/ffpython.cpp @@ -0,0 +1,608 @@ +#include "ffpython.h" + + +//! 获取python异常信息 + +int pyops_t::traceback(std::string& ret_) +{ + PyObject* err = PyErr_Occurred(); + + if (err != NULL) { + PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL; + PyObject *pyth_module = NULL, *pyth_func = NULL; + + PyErr_Fetch(&ptype, &pvalue, &ptraceback); + if (pvalue) + { + if (true == PyList_Check(pvalue)) + { + int64_t n = PyList_Size(pvalue); + for (int64_t i = 0; i < n; ++i) + { + PyObject *pystr = PyObject_Str(PyList_GetItem(pvalue, i)); + ret_ += PyString_AsString(pystr); + ret_ += "\n"; + Py_DECREF(pystr); + } + } + if (true == PyTuple_Check(pvalue)) + { + int64_t n = PyTuple_Size(pvalue); + for (int64_t i = 0; i < n; ++i) + { + PyObject* tmp_str = PyTuple_GetItem(pvalue, i); + if (true == PyTuple_Check(tmp_str)) + { + int64_t m = PyTuple_Size(tmp_str); + for (int64_t j = 0; j < m; ++j) + { + PyObject *pystr = PyObject_Str(PyTuple_GetItem(tmp_str, j)); + ret_ += PyString_AsString(pystr); + ret_ += ","; + Py_DECREF(pystr); + } + } + else + { + PyObject *pystr = PyObject_Str(tmp_str); + ret_ += PyString_AsString(pystr); + Py_DECREF(pystr); + } + ret_ += "\n"; + } + } + else + { + PyObject *pystr = PyObject_Str(pvalue); + if (pystr) + { + ret_ += PyString_AsString(pystr); + ret_ += "\n"; + Py_DECREF(pystr); + } + } + } + + /* See if we can get a full traceback */ + PyObject *module_name = PyString_FromString("traceback"); + pyth_module = PyImport_Import(module_name); + Py_DECREF(module_name); + + if (pyth_module && ptype && pvalue && ptraceback) + { + pyth_func = PyObject_GetAttrString(pyth_module, "format_exception"); + if (pyth_func && PyCallable_Check(pyth_func)) { + PyObject *pyth_val = PyObject_CallFunctionObjArgs(pyth_func, ptype, pvalue, ptraceback, NULL); + if (pyth_val && true == PyList_Check(pyth_val)) + { + int64_t n = PyList_Size(pyth_val); + for (int64_t i = 0; i < n; ++i) + { + PyObject* tmp_str = PyList_GetItem(pyth_val, i); + PyObject *pystr = PyObject_Str(tmp_str); + if (pystr) + { + ret_ += PyString_AsString(pystr); + + Py_DECREF(pystr); + } + ret_ += "\n"; + } + } + Py_XDECREF(pyth_val); + } + } + Py_XDECREF(pyth_func); + Py_XDECREF(pyth_module); + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + PyErr_Clear(); + return 0; + } + + return -1; +} + +ffpython_t::ffpython_t(ModInitFunc func) +{ + if (func) { + std::string modName = func(*this); + init(modName); + } + if (!Py_IsInitialized()) + Py_Initialize(); + rename_method(); + rename_pyclass(); +} +ffpython_t::~ffpython_t() +{ + clear_cache_pyobject(); +} + + +int ffpython_t::init_py() +{ + Py_Initialize(); + return 0; +} +int ffpython_t::final_py() +{ + Py_Finalize(); + return 0; +} + +int ffpython_t::add_path(const std::string& path_) +{ + char buff[1024]; + SAFE_SPRINTF(buff, sizeof(buff), "import sys\nif '%s' not in sys.path:\n\tsys.path.append('%s')\n", path_.c_str(), path_.c_str()); + PyRun_SimpleString(buff); + return 0; +} + +int ffpython_t::run_string(const std::string& py_) +{ + PyRun_SimpleString(py_.c_str()); + return 0; +} + +int ffpython_t::reload(const std::string& py_name_) +{ + PyObject *pName = NULL, *pModule = NULL; + std::string err_msg; + + pName = PyString_FromString(py_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return -1; + } + + PyObject *pNewMod = PyImport_ReloadModule(pModule); + Py_DECREF(pModule); + if (NULL == pNewMod) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return -1; + } + Py_DECREF(pNewMod); + return 0; +} +int ffpython_t::load(const std::string& py_name_) +{ + PyObject *pName = NULL, *pModule = NULL; + std::string err_msg; + + pName = PyString_FromString(py_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return -1; + } + + Py_DECREF(pModule); + return 0; +} + +int ffpython_t::init(const std::string& mod_name_, std::string doc_) +{ + m_mod_name = mod_name_; + m_mod_doc = doc_; + init_method(); + init_pyclass(); + + static std::vector* vtmp; + static std::vector* all_pyclass; + vtmp = &m_pymethod_defs; + all_pyclass = &m_all_pyclass; + static PyModuleDef EmbModule = { + PyModuleDef_HEAD_INIT, m_mod_name.c_str(), NULL, -1, &((*vtmp)[0]), + NULL, NULL, NULL, NULL + }; + struct TmpLambda { + static PyObject* PyInit_emb(void) + { + PyObject* retObj = PyModule_Create(&EmbModule); + + for (size_t i = 0; i < (*all_pyclass).size(); ++i) + { + if (PyType_Ready(&((*all_pyclass)[i].pytype_def)) < 0) + return retObj; + PyObject* tmpP = (PyObject*)(&((*all_pyclass)[i].pytype_def)); + Py_INCREF(tmpP); + PyModule_AddObject(retObj, (*all_pyclass)[i].class_real_name.c_str(), (PyObject *)&(*all_pyclass)[i].pytype_def); + } + + return retObj; + } + }; + PyImport_AppendInittab(m_mod_name.c_str(), TmpLambda::PyInit_emb); + + return 0; +} + +void ffpython_t::init_method() +{ + std::string mod_name_ = m_mod_name; + std::string doc_ = m_mod_doc; + + if (m_pymethod_defs.empty()) + { + m_pymethod_defs.reserve(m_func_info.size() + 1); + + for (size_t i = 0; i < m_func_info.size(); ++i) + { + PyMethodDef tmp = { m_func_info[i].func_impl_name.c_str(), m_func_info[i].func, + METH_VARARGS, m_func_info[i].doc_impl.c_str() }; + m_pymethod_defs.push_back(tmp); + } + PyMethodDef tmp = { NULL }; + m_pymethod_defs.push_back(tmp); + } + + return; +} +void ffpython_t::rename_method() +{ + for (size_t i = 0; i < m_func_info.size(); ++i) + { + std::string pystr_args; + std::string pystr_args_only_name; + for (int j = 0; j < m_func_info[i].args_num; ++j) + { + stringstream ss; + if (pystr_args.empty()) + { + ss << "a" << (j+1); + pystr_args += ss.str(); + } + else + { + ss << ", a" << (j+1); + pystr_args += ss.str(); + } + } + pystr_args_only_name = pystr_args; + for (int j = 0; j < m_func_info[i].option_args_num; ++j) + { + stringstream ss; + if (pystr_args.empty()) + { + ss << "a" << (m_func_info[i].args_num + j+1); + std::string tmp = ss.str(); + pystr_args_only_name += tmp; + pystr_args += tmp + " = None"; + } + else + { + ss << ", a" << (m_func_info[i].args_num + j+1); + std::string tmp = ss.str(); + pystr_args_only_name += tmp; + pystr_args += tmp + " = None"; + } + } + if (!pystr_args_only_name.empty()) + pystr_args_only_name += ","; + + std::ostringstream oss;//创建一个流 + oss << m_func_info[i].func_addr;//把值传递如流中 + std::string funcAddrStr = oss.str();//获取转换后的字符转并将其写入result + + char buff[1024]; + SAFE_SPRINTF(buff, sizeof(buff), + "_tmp_ff_ = None\nif '%s' in globals():\n\t_tmp_ff_ = globals()['%s']\n" + "def %s(%s):\n" + "\t'''%s'''\n" + "\treturn %s.%s(%s,(%s))\n" + "import %s\n" + "%s.%s = %s\n" + "%s = None\n" + "if _tmp_ff_:\n\tglobals()['%s'] = _tmp_ff_\n_tmp_ff_ = None\n", + m_func_info[i].func_name.c_str(), m_func_info[i].func_name.c_str(), + m_func_info[i].func_name.c_str(), pystr_args.c_str(), + m_func_info[i].doc.c_str(), + m_mod_name.c_str(), m_func_info[i].func_impl_name.c_str(), funcAddrStr.c_str(), pystr_args_only_name.c_str(), + m_mod_name.c_str(), + m_mod_name.c_str(), m_func_info[i].func_name.c_str(), m_func_info[i].func_name.c_str(), + m_func_info[i].func_name.c_str(), + m_func_info[i].func_name.c_str() + ); + + //printf(buff); + PyRun_SimpleString(buff); + } +} + +int ffpython_t::init_pyclass() +{ + for (size_t i = 0; i < m_all_pyclass.size(); ++i) + { + m_all_pyclass[i].static_pytype_info->mod_name = m_mod_name; + if (false == m_all_pyclass[i].inherit_name.empty()) + { + pyclass_regigster_tool_t* inherit_class = get_pyclass_info_by_name(m_all_pyclass[i].inherit_name); + assert(inherit_class && "base class must be registed"); + for (size_t n = 0; n < inherit_class->methods_info.size(); ++n) + { + const std::string& method_name = inherit_class->methods_info[n].func_name; + if (false == is_method_exist(m_all_pyclass[i].methods_info, method_name)) + { + m_all_pyclass[i].methods_info.push_back(inherit_class->methods_info[n]); + } + } + for (size_t n = 0; n < inherit_class->propertys_info.size(); ++n) + { + const std::string& property_name = inherit_class->propertys_info[n].property_name; + if (false == is_property_exist(m_all_pyclass[i].propertys_info, property_name)) + { + m_all_pyclass[i].propertys_info.push_back(inherit_class->propertys_info[n]); + } + } + } + //! init class property + for (size_t j = 0; j < m_all_pyclass[i].propertys_info.size(); ++j) + { + PyGetSetDef tmp = {(char*)m_all_pyclass[i].propertys_info[j].property_name.c_str(), + m_all_pyclass[i].propertys_info[j].getter_func, + m_all_pyclass[i].propertys_info[j].setter_func, + (char*)m_all_pyclass[i].propertys_info[j].doc.c_str(), + m_all_pyclass[i].propertys_info[j].ptr + }; + m_all_pyclass[i].pyproperty_def.push_back(tmp); + } + PyGetSetDef tmp_property_def = {NULL}; + m_all_pyclass[i].pyproperty_def.push_back(tmp_property_def); + //! init class method + for (size_t j = 0; j < m_all_pyclass[i].methods_info.size(); ++j) + { + PyMethodDef tmp = {m_all_pyclass[i].methods_info[j].func_real_name.c_str(), + m_all_pyclass[i].methods_info[j].func, + METH_VARARGS, + m_all_pyclass[i].methods_info[j].doc.c_str() + }; + m_all_pyclass[i].pymethod_def.push_back(tmp); + + } + PyMethodDef tmp_del = {"delete", + m_all_pyclass[i].delete_func, + METH_VARARGS, + "delete obj" + }; + m_all_pyclass[i].pymethod_def.push_back(tmp_del); + PyMethodDef tmp_method_def = {NULL}; + m_all_pyclass[i].pymethod_def.push_back(tmp_method_def); + + m_all_pyclass[i].class_name_with_mod = m_mod_name + "." + m_all_pyclass[i].class_name; + m_all_pyclass[i].class_reel_name_with_mod = m_mod_name + "." + m_all_pyclass[i].class_real_name; + + PyTypeObject tmp_pytype_def = + { + PyVarObject_HEAD_INIT(NULL, 0) + m_all_pyclass[i].class_reel_name_with_mod.c_str(), /*tp_name*/ + m_all_pyclass[i].type_size, /*tp_size*/ + 0, /*tp_itemsize*/ + (destructor)m_all_pyclass[i].dector, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + m_all_pyclass[i].doc.c_str(), /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + &(m_all_pyclass[i].pymethod_def.front()),//Noddy_methods, /* tp_methods */ + 0,//Noddy_members, /* tp_members */ + &(m_all_pyclass[i].pyproperty_def.front()),//Noddy_getseters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)m_all_pyclass[i].init, /* tp_init */ + 0, /* tp_alloc */ + m_all_pyclass[i].ctor, /* tp_new */ + }; + m_all_pyclass[i].pytype_def = tmp_pytype_def; + m_all_pyclass[i].static_pytype_info->pytype_def = &m_all_pyclass[i].pytype_def; + cpp_to_pyclass_reg_info_t::add(m_all_pyclass[i].class_name, m_all_pyclass[i].inherit_name, &m_all_pyclass[i].pytype_def); + } + + return 0; +} + +void ffpython_t::rename_pyclass() +{ + for (size_t i = 0; i < m_all_pyclass.size(); ++i) + { + stringstream str_def_args; + stringstream str_init_args; + for (int a = 0; a < m_all_pyclass[i].args_num; ++a) + { + str_def_args << "a" << (a + 1) << ","; + str_init_args << "a" << (a + 1) << ","; + } + for (int b = 0; b < m_all_pyclass[b].option_args_num; ++b) + { + str_def_args << "a" << (m_all_pyclass[i].args_num + b + 1) << " = None,"; + str_init_args << "a" << (m_all_pyclass[i].args_num + b + 1) << ","; + } + + char buff[1024]; + SAFE_SPRINTF(buff, sizeof(buff), + "_tmp_ff_ = None\nif '%s' in globals():\n\t_tmp_ff_ = globals()['%s']\n" + "import %s\n" + "class %s(object):\n" + "\t'''%s'''\n" + "\tdef __init__(self, %s assign_obj_ = 0):\n" + "\t\t'''%s'''\n" + "\t\tif True == isinstance(assign_obj_, %s):\n" + "\t\t\tself.obj = assign_obj_\n" + "\t\t\treturn\n" + "\t\tself.obj = %s(0,(%s))\n", + m_all_pyclass[i].class_name.c_str(), m_all_pyclass[i].class_name.c_str(), + m_mod_name.c_str(), + m_all_pyclass[i].class_name.c_str(), + m_all_pyclass[i].doc.c_str(), + str_def_args.str().c_str(), + "init class", + m_all_pyclass[i].class_reel_name_with_mod.c_str(), + m_all_pyclass[i].class_reel_name_with_mod.c_str(), str_init_args.str().c_str() + ); + + std::string gen_class_str = buff; + SAFE_SPRINTF(buff, sizeof(buff), + "\tdef delete(self):\n" + "\t\t'''delete obj'''\n" + "\t\tself.obj.delete()\n"); + gen_class_str += buff; + //! 增加析构函数 + //! 增加属性 + for (size_t c = 0; c < m_all_pyclass[i].propertys_info.size(); ++c) + { + SAFE_SPRINTF(buff, sizeof(buff), + "\tdef get_%s(self):\n" + "\t\treturn self.obj.%s\n" + "\tdef set_%s(self, v):\n" + "\t\tself.obj.%s = v\n" + "\t@property\n" + "\tdef %s(self):\n" + "\t\treturn self.obj.%s\n" + "\t@%s.setter\n" + "\tdef %s(self, v):\n" + "\t\tself.obj.%s = v\n", + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str() + ); + gen_class_str += buff; + } + + for (size_t m = 0; m < m_all_pyclass[i].methods_info.size(); ++m) + { + std::string pystr_args; + std::string pystr_args_only_name; + for (int j = 0; j < m_all_pyclass[i].methods_info[m].args_num; ++j) + { + stringstream ss; + if (pystr_args.empty()) + { + ss << "a" << (j + 1); + pystr_args += ss.str(); + } + else + { + ss << ", a" << (j + 1); + pystr_args += ss.str(); + } + } + pystr_args_only_name = pystr_args; + for (int j = 0; j < m_all_pyclass[i].methods_info[m].option_args_num; ++j) + { + stringstream ss; + if (pystr_args.empty()) + { + ss << "a" << (m_all_pyclass[i].methods_info[m].args_num + j + 1); + std::string tmp = ss.str(); + pystr_args_only_name += tmp; + pystr_args += tmp + " = None"; + } + else + { + ss << ", a" << (m_all_pyclass[i].methods_info[m].args_num + j + 1); + std::string tmp = ss.str(); + pystr_args_only_name += tmp; + pystr_args += tmp + " = None"; + } + } + if (!pystr_args_only_name.empty()) + pystr_args_only_name += ","; + + std::ostringstream oss;//创建一个流 + oss << m_all_pyclass[i].methods_info[m].func_addr;//把值传递如流中 + std::string funcAddrStr = oss.str();//获取转换后的字符转并将其写入result + + SAFE_SPRINTF(buff, sizeof(buff), + "\tdef %s(self,%s):\n" + "\t\t'''%s'''\n" + "\t\treturn self.obj.%s(%s,(%s))\n" + , m_all_pyclass[i].methods_info[m].func_name.c_str(), pystr_args.c_str(), + m_all_pyclass[i].methods_info[m].doc.c_str(), + m_all_pyclass[i].methods_info[m].func_real_name.c_str(), funcAddrStr.c_str(), pystr_args_only_name.c_str() + ); + gen_class_str += buff; + } + SAFE_SPRINTF(buff, sizeof(buff), + "%s.%s = %s\n" + "%s = None\n" + "if _tmp_ff_:\n\tglobals()['%s'] = _tmp_ff_\n_tmp_ff_ = None\n", + m_mod_name.c_str(), m_all_pyclass[i].class_name.c_str(), m_all_pyclass[i].class_name.c_str(), + m_all_pyclass[i].class_name.c_str(), + m_all_pyclass[i].class_name.c_str() + ); + gen_class_str += buff; + //printf(gen_class_str.c_str()); + PyRun_SimpleString(gen_class_str.c_str()); + } +} + +bool ffpython_t::is_method_exist(const std::vector& src_, const std::string& new_) +{ + for (size_t i = 0; i < src_.size(); ++i) + { + if (new_ == src_[i].func_name) + { + return true; + } + } + return false; +} +bool ffpython_t::is_property_exist(const std::vector& src_, const std::string& new_) +{ + for (size_t i = 0; i < src_.size(); ++i) + { + if (new_ == src_[i].property_name) + { + return true; + } + } + return false; +} +pyclass_regigster_tool_t* ffpython_t::get_pyclass_info_by_name(const std::string& name_) +{ + for (size_t i = 0; i < m_all_pyclass.size(); ++i) + { + if (m_all_pyclass[i].class_name == name_) + { + return &(m_all_pyclass[i]); + } + } + return NULL; +} + diff --git a/pyops_base.h b/pyops_base.h new file mode 100644 index 0000000..29a8ab9 --- /dev/null +++ b/pyops_base.h @@ -0,0 +1,1130 @@ +#ifndef __PYOPS_BASE_ +#define __PYOPS_BASE_ + + +#ifdef _DEBUG + #undef _DEBUG + #include + #define _DEBUG +#else + #include +#endif +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#define SAFE_SPRINTF _snprintf_s +#define PTR_NUMBER int64_t +#else +#define SAFE_SPRINTF snprintf +#define PTR_NUMBER int64_t +#endif + +#define PyString_Check PyUnicode_Check +#define PyString_AsString(pvalue_) PyUnicode_AsUTF8(pvalue_) +#define PyString_AsStringAndSize(pvalue_, pDestPtr, nLen) *pDestPtr = PyUnicode_AsUTF8AndSize(pvalue_, nLen) +#define PyString_FromStringAndSize PyUnicode_FromStringAndSize +#define PyString_FromString PyUnicode_FromString + + +//! 获取python异常信息 +struct pyops_t +{ + static int traceback(std::string& ret_); +}; +struct cpp_void_t{}; + +//! 用于抽取类型、类型对应的引用 +template +struct type_ref_traits_t; + +//! 用于python 可选参数 +template +struct pyoption_t +{ + typedef typename type_ref_traits_t::value_t value_t; + pyoption_t():m_set_flag(false){} + bool is_set() const { return m_set_flag;} + void set() { m_set_flag = true;} + value_t& value() { return m_value;} + const value_t& value() const{ return m_value;} + + const value_t& value(const value_t& default_) + { + if (is_set()) + return m_value; + else + return default_; + } + bool m_set_flag; + value_t m_value; +}; +//! 用于判断是否是可选参数 +template +struct pyoption_traits_t; + +//! pytype_traits_t 封装 PyLong_FromLong 相关的操作,用于为调用python生成参数 +template +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const char* const val_) + { + return PyString_FromString(val_); + } + /* + static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) + { + if (true == PyString_Check(pvalue_)) + { + m_ret = PyString_AsString(pvalue_); + return 0; + } + return -1; + } + */ + static const char* get_typename() { return "std::string";} +}; + +//! 用于调用python函数,生成tuple类型的python函数参数的工具类 +struct pycall_arg_t +{ + pycall_arg_t(int arg_num): + arg_index(0), + pargs_tuple(PyTuple_New(arg_num)) + {} + ~pycall_arg_t() + { + release(); + } + PyObject * get_args() const + { + return pargs_tuple; + } + template + pycall_arg_t& add(const T& val_) + { + if (arg_index < PyTuple_Size(pargs_tuple)) + { + PyObject* tmp_arg = pytype_traits_t::pyobj_from_cppobj(val_); + PyTuple_SetItem(pargs_tuple, arg_index, tmp_arg); + ++arg_index; + } + return *this; + } + void release() + { + if (pargs_tuple) + { + Py_DECREF(pargs_tuple); + pargs_tuple = NULL; + } + } + int arg_index; + PyObject * pargs_tuple; +}; + +//! 用于调用python函数,获取返回值的工具类 +class pytype_tool_t +{ +public: + virtual ~pytype_tool_t(){}; + virtual int parse_value(PyObject *pvalue_) = 0; + virtual const char* return_type() {return "";} + virtual bool need_release() { return false; } +}; + +//! 用于调用python函数,获取返回值的工具泛型类 +template +class pytype_tool_impl_t; +//! 封装调用python函数的C API +struct pycall_t +{ + static int call_func(PyObject *pModule, const std::string& mod_name_, const std::string& func_name_, + pycall_arg_t& pyarg_, pytype_tool_t& pyret_, std::string& err_) + { + PyObject *pFunc = PyObject_GetAttrString(pModule, func_name_.c_str()); + if (pFunc && PyCallable_Check(pFunc)) { + PyObject *pArgs = pyarg_.get_args(); + PyObject *pValue = PyObject_CallObject(pFunc, pArgs); + pyarg_.release();//! 等价于Py_DECREF(pArgs); + + if (pValue != NULL) { + if (pyret_.parse_value(pValue)) + { + err_ += "value returned is not "; + err_ += pyret_.return_type(); + err_ += std::string(" ") + func_name_ + " in " + mod_name_; + } + if (pyret_.need_release()){ + Py_DECREF(pValue); + } + } + } + else + { + err_ += "Cannot find function "; + err_ += func_name_ + " in " + mod_name_ + ","; + } + + Py_XDECREF(pFunc); + if (PyErr_Occurred()) + { + pyops_t::traceback(err_); + return 0; + } + return 0; + } + static int call_func_obj(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_t& pyret_, std::string& err_) + { + if (pFunc && PyCallable_Check(pFunc)) { + PyObject *pArgs = pyarg_.get_args(); + PyObject *pValue = PyObject_CallObject(pFunc, pArgs); + pyarg_.release();//! 等价于Py_DECREF(pArgs); + + if (pValue != NULL) { + if (pyret_.parse_value(pValue)) + { + err_ += "value returned is not "; + err_ += pyret_.return_type(); + } + if (pyret_.need_release()){ + Py_DECREF(pValue); + } + } + } + else + { + err_ += "invalid function"; + } + + if (PyErr_Occurred()) + { + pyops_t::traceback(err_); + return 0; + } + return 0; + } + template + static const T& call(const std::string& mod_name_, const std::string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); + template + static const T& call_obj_method(PyObject *pObj, const std::string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); + template + static const T& call_lambda(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); +}; +//! 用于扩展python的工具类,用来解析参数 +struct pyext_tool_t; + + +template +struct pyext_return_tool_t; + +//! 用于扩展python,生成pyobject类型的返回值给python +template +struct pyext_func_traits_t; + +//! 用于扩展python,traits出注册给python的函数接口 +#ifndef PYCTOR +#define PYCTOR int (*) +#endif +//! 表示void类型,由于void类型不能return,用void_ignore_t适配 +template +struct void_ignore_t; + +template +struct void_ignore_t +{ + typedef T value_t; +}; + +template<> +struct void_ignore_t +{ + typedef cpp_void_t value_t; +}; + +#define RET_V typename void_ignore_t::value_t + +//! 记录各个基类和子类的相互关系 +struct cpp_to_pyclass_reg_info_t +{ + struct inherit_info_t + { + inherit_info_t():pytype_def(NULL){} + PyTypeObject* pytype_def; + std::string inherit_name; + std::set all_child; + }; + typedef std::map inherit_info_map_t; + static inherit_info_map_t& get_all_info() + { + static inherit_info_map_t inherit_info; + return inherit_info; + } + + static void add(const std::string& child_, const std::string& base_, PyTypeObject* def_) + { + inherit_info_t tmp; + tmp.inherit_name = base_; + tmp.pytype_def = def_; + get_all_info()[child_] = tmp; + get_all_info()[base_].all_child.insert(def_); + } + static bool is_instance(PyObject* pysrc, const std::string& class_) + { + inherit_info_map_t& inherit_info = get_all_info(); + inherit_info_t& tmp = inherit_info[class_]; + if (tmp.pytype_def && PyObject_TypeCheck(pysrc, tmp.pytype_def)) + { + return true; + } + for (std::set::iterator it = tmp.all_child.begin(); it != tmp.all_child.end(); ++it) + { + if (*it && PyObject_TypeCheck(pysrc, *it)) + { + return true; + } + } + + return false; + } + +}; + + +//! 记录C++ class 对应到python中的名称、参数信息等,全局 +struct static_pytype_info_t +{ + std::string class_name; + std::string mod_name; + int total_args_num; + PyTypeObject* pytype_def; +}; + +//! 工具类,用于生成分配python class的接口,包括分配、释放 +template +struct pyclass_base_info_t +{ + struct obj_data_t + { + obj_data_t():obj(NULL){} + + PyObject_HEAD + T* obj; + bool forbid_release; + void disable_auto_release(){ forbid_release = true; } + void release() + { + if (obj) + { + delete obj; + obj = NULL; + } + } + }; + + static void free_obj(obj_data_t* self) + { + if (false == self->forbid_release && self->obj) + { + self->release(); + } + self->ob_base.ob_type->tp_free((PyObject*)self); + } + + static PyObject *alloc_obj(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + obj_data_t *self = (obj_data_t *)type->tp_alloc(type, 0); + return (PyObject *)self; + } + static PyObject *release(PyTypeObject *type, PyObject *args) + { + obj_data_t *self = (obj_data_t *)type; + self->release(); + return Py_BuildValue("i", 1); + } + static static_pytype_info_t pytype_info; +}; +template +static_pytype_info_t pyclass_base_info_t::pytype_info; + +//! 方便生成pyclass 初始化函数 +template +struct pyclass_ctor_tool_t; + +//! used to gen method of py class +template +struct pyclass_method_gen_t; + +//! 防止出现指针为NULL调用出错 +#define NULL_PTR_GUARD(X) if (NULL == X) {PyErr_SetString(PyExc_TypeError, "obj data ptr NULL");return NULL;} + +//! 用于生成python 的getter和setter接口,适配于c++ class的成员变量 +template +struct pyclass_member_func_gen_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + typedef RET CLASS_TYPE::* property_ptr_t; + + static PyObject *getter_func(obj_data_t *self, void *closure) + { + property_ptr_t property_ptr; + ::memcpy((void*)&property_ptr, (const void*)&closure, sizeof(closure)); + NULL_PTR_GUARD(self->obj); + CLASS_TYPE* p = self->obj; + return pytype_traits_t::pyobj_from_cppobj(p->*property_ptr); + } + static int setter_func(obj_data_t *self, PyObject *value, void *closure) + { + property_ptr_t property_ptr; + ::memcpy((void*)&property_ptr, (const void*)&closure, sizeof(closure)); + CLASS_TYPE* p = self->obj; + + return pytype_traits_t::pyobj_to_cppobj(value, p->*property_ptr); + } +}; + +//! 用于C++ 注册class的工具类,会记录class对应的名称、成员方法、成员变量 +class pyclass_regigster_tool_t +{ +public: + struct method_info_t + { + PyCFunction func; + std::string func_name; + std::string func_real_name; + std::string doc; + std::string doc_real; + int args_num; + int option_args_num; + PTR_NUMBER func_addr; + }; + struct property_info_t + { + void* ptr; + std::string property_name; + std::string doc; + getter getter_func; + setter setter_func; + }; + virtual ~pyclass_regigster_tool_t(){} + + typedef PyObject *(*pyobj_alloc_t)(PyTypeObject*, PyObject*, PyObject*); + + std::string class_name; + std::string class_real_name; + std::string class_name_with_mod; + std::string class_reel_name_with_mod; + std::string inherit_name; + int type_size; + std::string doc; + int args_num; + int option_args_num; + destructor dector; + initproc init; + pyobj_alloc_t ctor; + + //! member functions + PyCFunction delete_func; + std::vector methods_info; + //! property + std::vector propertys_info; + //! for init module + PyTypeObject pytype_def; + //! method + std::vector pymethod_def; + //! property + std::vector pyproperty_def; + + //! 静态类型需要全局记录该类型被注册成神马python 类型 + static_pytype_info_t* static_pytype_info; + + template + pyclass_regigster_tool_t& reg(FUNC f_, const std::string& func_name_, std::string doc_ = "") + { + method_info_t tmp; + tmp.func_name = func_name_; + tmp.func_real_name = func_name_ + "_internal_"; + tmp.doc = doc_; + tmp.doc_real = "internal use"; + tmp.func = (PyCFunction)pyclass_method_gen_t::pymethod; + tmp.args_num = pyclass_method_gen_t::args_num(); + tmp.option_args_num = pyclass_method_gen_t::option_args_num(); + ::memcpy((void*)&tmp.func_addr, (const void*)&f_, sizeof(void*)); + methods_info.push_back(tmp); + return *this; + } + template + pyclass_regigster_tool_t& reg_property(RET CLASS_TYPE::* member_, const std::string& member_name_, std::string doc_ = "") + { + property_info_t tmp; + ::memcpy((void*)&tmp.ptr, (const void*)&member_, sizeof(member_)); + tmp.property_name = member_name_; + tmp.doc = doc_; + tmp.getter_func = (getter)pyclass_member_func_gen_t::getter_func; + tmp.setter_func = (setter)pyclass_member_func_gen_t::setter_func; + propertys_info.push_back(tmp); + return *this; + } +}; + + +template +struct type_ref_traits_t +{ + typedef T value_t; + typedef T& ref_t; + value_t value; +}; +template +struct type_ref_traits_t +{ + typedef T value_t; + typedef T& ref_t; + value_t value; +}; +template +struct type_ref_traits_t +{ + typedef T value_t; + typedef T& ref_t; + value_t value; +}; +//! 用于判断是否是可选参数 +template +struct pyoption_traits_t +{ + static int is() { return 0;} +}; +template +struct pyoption_traits_t > +{ + static int is() { return 1;} +}; + + +template<>//typename T> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const long& val_) + { + return PyLong_FromLong(long(val_)); + } + static int pyobj_to_cppobj(PyObject *pvalue_, long& m_ret) + { + if (true == PyLong_Check(pvalue_)) + { + m_ret = (long)PyLong_AsLong(pvalue_); + return 0; + } + /*else if (true == PyInt_Check(pvalue_)) + { + m_ret = (long)PyInt_AsLong(pvalue_); + return 0; + }*/ + return -1; + } + static const char* get_typename() { return "long";} +}; + +#define IMPL_INT_CODE(X) \ +template<> \ +struct pytype_traits_t \ +{ \ + static PyObject* pyobj_from_cppobj(const X& val_) \ + { \ + return PyLong_FromLong(long(val_)); \ + } \ + static int pyobj_to_cppobj(PyObject *pvalue_, X& m_ret) \ + { \ + if (true == PyLong_Check(pvalue_)) \ + { \ + m_ret = (X)PyLong_AsLong(pvalue_); \ + return 0; \ + } \ + return -1; \ + } \ + static const char* get_typename() { return #X;} \ +}; + +IMPL_INT_CODE(int) +IMPL_INT_CODE(unsigned int) +IMPL_INT_CODE(short) +IMPL_INT_CODE(unsigned short) +IMPL_INT_CODE(char) +IMPL_INT_CODE(unsigned char) + +#ifdef _WIN32 +IMPL_INT_CODE(unsigned long) +IMPL_INT_CODE(int64_t) +#else +#ifndef __x86_64__ +IMPL_INT_CODE(int64_t) +#endif +IMPL_INT_CODE(uint64_t) +#endif + +template +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const T* val_) + { + const std::string& mod_name = pyclass_base_info_t::pytype_info.mod_name; + const std::string& class_name = pyclass_base_info_t::pytype_info.class_name; + PyObject *pName = NULL, *pModule = NULL, *pValue = NULL; + + if (class_name.empty()) + return pytype_traits_t::pyobj_from_cppobj(PTR_NUMBER(val_)); + + pName = PyString_FromString(mod_name.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + if (PyErr_Occurred()) + PyErr_Print(); + fprintf(stderr, "Failed to load \"%s\"\n", mod_name.c_str()); + assert(NULL && "this can not be happened"); + return NULL; + } + PyObject *pyclass = PyObject_GetAttrString(pModule, class_name.c_str()); + if (pyclass && PyCallable_Check(pyclass)) { + PyObject *pArgs = PyTuple_New(pyclass_base_info_t::pytype_info.total_args_num+1); + for (int i = 0; i< pyclass_base_info_t::pytype_info.total_args_num; ++i) + { + PyTuple_SetItem(pArgs, i, pytype_traits_t::pyobj_from_cppobj(0)); + } + + PyObject *palloc = pyclass_base_info_t::alloc_obj(pyclass_base_info_t::pytype_info.pytype_def, NULL, NULL); + typename pyclass_base_info_t::obj_data_t* pdest_obj = (typename pyclass_base_info_t::obj_data_t*)palloc; + //pdest_obj->obj = val_; + ::memcpy((void*)&pdest_obj->obj, (const void*)&val_, sizeof(pdest_obj->obj)); + pdest_obj->disable_auto_release(); + PyTuple_SetItem(pArgs, pyclass_base_info_t::pytype_info.total_args_num, palloc); + pValue = PyObject_CallObject(pyclass, pArgs); + Py_XDECREF(pArgs); + } + + Py_XDECREF(pyclass); + Py_DECREF(pModule); + return pValue; + } + + static int pyobj_to_cppobj(PyObject *pvalue_, T*& m_ret) + { + PyObject *pysrc = PyObject_GetAttrString(pvalue_, "obj"); + //!PyObject_TypeCheck(pysrc, pyclass_base_info_t::pytype_info.pytype_def)) { + if (NULL == pysrc || false == cpp_to_pyclass_reg_info_t::is_instance(pysrc, pyclass_base_info_t::pytype_info.class_name)) + { + Py_XDECREF(pysrc); + return -1; + } + typename pyclass_base_info_t::obj_data_t* pdest_obj = (typename pyclass_base_info_t::obj_data_t*)pysrc; + + m_ret = pdest_obj->obj; + Py_XDECREF(pysrc); + return 0; + } + + static const char* get_typename() { return pyclass_base_info_t::pytype_info.class_name.c_str();} +}; + +template +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(T* val_) + { + return pytype_traits_t::pyobj_from_cppobj(val_); + } + static int pyobj_to_cppobj(PyObject *pvalue_,T*& m_ret) + { + return pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret); + } + static const char* get_typename() { return pyclass_base_info_t::pytype_info.class_name.c_str();} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(PyObject* val_) + { + return val_; + } + static int pyobj_to_cppobj(PyObject *pvalue_, PyObject*& m_ret) + { + m_ret = pvalue_; + return 0; + } + static const char* get_typename() { return "PyObject";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const char* const val_) + { + return PyString_FromString(val_); + } + /* + static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) + { + if (true == PyString_Check(pvalue_)) + { + m_ret = PyString_AsString(pvalue_); + return 0; + } + return -1; + } + */ + static const char* get_typename() { return "std::string";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const char*& val_) + { + return PyString_FromString(val_); + } + /* + static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) + { + if (true == PyString_Check(pvalue_)) + { + m_ret = PyString_AsString(pvalue_); + return 0; + } + return -1; + } + */ + static const char* get_typename() { return "std::string";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(bool val_) + { + if (val_) + { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; + } + static int pyobj_to_cppobj(PyObject *pvalue_, bool& m_ret) + { + if (Py_False == pvalue_|| Py_None == pvalue_) + { + m_ret = false; + } + else + { + m_ret = true; + } + return 0; + } + static const char* get_typename() { return "bool";} +}; + +template +struct pytype_traits_t > +{ + static int pyobj_to_cppobj(PyObject *pvalue_, pyoption_t& m_ret) + { + if (Py_None == pvalue_) + { + return 0; + } + else if (0 == pytype_traits_t::value_t>::pyobj_to_cppobj(pvalue_, m_ret.value())) + { + m_ret.std::set(); + return 0; + } + return -1; + } + static const char* get_typename() { return "pyoption_t";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const std::string& val_) + { + return PyString_FromStringAndSize(val_.c_str(), val_.size()); + } + static int pyobj_to_cppobj(PyObject *pvalue_, std::string& m_ret) + { + if (true == PyString_Check(pvalue_)) + { + const char* pDest = NULL; + Py_ssize_t nLen = 0; + PyString_AsStringAndSize(pvalue_, &pDest, &nLen); + + m_ret.assign(pDest, nLen); + return 0; + } + else if (true == PyUnicode_Check(pvalue_)) + { + const char* pDest = NULL; + Py_ssize_t nLen = 0; + PyString_AsStringAndSize(pvalue_, &pDest, &nLen); + m_ret.assign(pDest, nLen); + return 0; + /* +#ifdef _WIN32 + PyObject* retStr = PyUnicode_AsEncodedString(pvalue_, "gbk", ""); +#else + PyObject* retStr = PyUnicode_AsUTF8String(pvalue_); +#endif + if (retStr) + { + m_ret = PyString_AsString(retStr); + Py_XDECREF(retStr); + return 0; + } + */ + } + return -1; + } + static const char* get_typename() { return "std::string";} +}; + +//#ifdef _WIN32 +//template<> +//struct pytype_traits_t +//{ +// static PyObject* pyobj_from_cppobj(const wstring& wstr) +// { +// return PyUnicode_FromWideChar(wstr.c_str(), wstr.length()); +// } +// static int pyobj_to_cppobj(PyObject *pvalue_, wstring& wstr_ret) +// { +// if (true == PyString_Check(pvalue_)) +// { +// PyObject* retStr = PyUnicode_FromObject(pvalue_); +// if (retStr) +// { +// int n = PyUnicode_GetSize(retStr); +// wstr_ret.resize(n); +// n = PyUnicode_AsWideChar((PyUnicodeObject*)retStr, &(wstr_ret[0]), n); +// Py_XDECREF(retStr); +// return 0; +// } +// return 0; +// } +// else if (true == PyUnicode_Check(pvalue_)) +// { +// int n = PyUnicode_GetSize(pvalue_); +// wstr_ret.resize(n); +// n = PyUnicode_AsWideChar((PyUnicodeObject*)pvalue_, &(wstr_ret[0]), n); +// return 0; +// } +// return -1; +// } +// static const char* get_typename() { return "wstring";} +//}; +//#endif + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(float val_) + { + return PyFloat_FromDouble(double(val_)); + } + static int pyobj_to_cppobj(PyObject *pvalue_, float& m_ret) + { + if (true == PyFloat_Check(pvalue_)) + { + m_ret = (float)PyFloat_AsDouble(pvalue_); + return 0; + } + return -1; + } + static const char* get_typename() { return "float";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(double val_) + { + return PyFloat_FromDouble(val_); + } + static int pyobj_to_cppobj(PyObject *pvalue_, double& m_ret) + { + if (true == PyFloat_Check(pvalue_)) + { + m_ret = PyFloat_AsDouble(pvalue_); + return 0; + } + return -1; + } + static const char* get_typename() { return "double";} +}; + +template +struct pytype_traits_t > +{ + static PyObject* pyobj_from_cppobj(const std::vector& val_) + { + PyObject* ret = PyList_New(val_.size()); + for (size_t i = 0; i < val_.size(); ++i) + { + PyList_SetItem(ret, i, pytype_traits_t::pyobj_from_cppobj(val_[i])); + } + return ret; + } + static int pyobj_to_cppobj(PyObject *pvalue_, std::vector& m_ret) + { + m_ret.clear(); + if (true == PyTuple_Check(pvalue_)) + { + int64_t n = PyTuple_Size(pvalue_); + for (int64_t i = 0; i < n; ++i) + { + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyTuple_GetItem(pvalue_, i))) + { + return -1; + } + m_ret.push_back(ret_tool.get_value()); + } + return 0; + } + else if (true == PyList_Check(pvalue_)) + { + int64_t n = PyList_Size(pvalue_); + for (int64_t i = 0; i < n; ++i) + { + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyList_GetItem(pvalue_, i))) + { + return -1; + } + m_ret.push_back(ret_tool.get_value()); + } + return 0; + } + return -1; + } + static const char* get_typename() { return "std::vector";} +}; +template +struct pytype_traits_t > +{ + static PyObject* pyobj_from_cppobj(const std::list& val_) + { + size_t n = val_.size(); + PyObject* ret = PyList_New(n); + int i = 0; + for (typename std::list::const_iterator it = val_.begin(); it != val_.end(); ++it) + { + PyList_SetItem(ret, i++, pytype_traits_t::pyobj_from_cppobj(*it)); + } + return ret; + } + static int pyobj_to_cppobj(PyObject *pvalue_, std::list& m_ret) + { + pytype_tool_impl_t ret_tool; + if (true == PyTuple_Check(pvalue_)) + { + int64_t n = PyTuple_Size(pvalue_); + for (int64_t i = 0; i < n; ++i) + { + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyTuple_GetItem(pvalue_, i))) + { + return -1; + } + m_ret.push_back(ret_tool.get_value()); + } + return 0; + } + else if (true == PyList_Check(pvalue_)) + { + int64_t n = PyList_Size(pvalue_); + for (int64_t i = 0; i < n; ++i) + { + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyList_GetItem(pvalue_, i))) + { + return -1; + } + m_ret.push_back(ret_tool.get_value()); + } + return 0; + } + return -1; + } + static const char* get_typename() { return "std::list";} +}; +template +struct pytype_traits_t > +{ + static PyObject* pyobj_from_cppobj(const std::set& val_) + { + PyObject* ret = PySet_New(NULL); + for (typename std::set::const_iterator it = val_.begin(); it != val_.end(); ++it) + { + PyObject *v = pytype_traits_t::pyobj_from_cppobj(*it); + PySet_Add(ret, v); + Py_DECREF(v); + } + return ret; + } + static int pyobj_to_cppobj(PyObject *pvalue_, std::set& m_ret) + { + m_ret.clear(); + pytype_tool_impl_t ret_tool; + PyObject *iter = PyObject_GetIter(pvalue_); + PyObject *item = NULL; + while (NULL != iter && NULL != (item = PyIter_Next(iter))) + { + T tmp(); + if (pytype_traits_t::pyobj_to_cppobj(item, tmp)) + { + Py_DECREF(item); + Py_DECREF(iter); + return -1; + } + m_ret.insert(tmp); + Py_DECREF(item); + } + if (iter) + { + Py_DECREF(iter); + return 0; + } + return -1; + } + static const char* get_typename() { return "std::set";} +}; +template +struct pytype_traits_t > +{ + static PyObject* pyobj_from_cppobj(const std::map& val_) + { + PyObject* ret = PyDict_New(); + for (typename std::map::const_iterator it = val_.begin(); it != val_.end(); ++it) + { + PyObject *k = pytype_traits_t::pyobj_from_cppobj(it->first); + PyObject *v = pytype_traits_t::pyobj_from_cppobj(it->second); + PyDict_SetItem(ret, k, v); + Py_DECREF(k); + Py_DECREF(v); + } + return ret; + } + static int pyobj_to_cppobj(PyObject *pvalue_, std::map& m_ret) + { + m_ret.clear(); + pytype_tool_impl_t ret_tool_T; + pytype_tool_impl_t ret_tool_R; + if (true == PyDict_Check(pvalue_)) + { + PyObject *key = NULL, *value = NULL; + Py_ssize_t pos = 0; + + while (PyDict_Next(pvalue_, &pos, &key, &value)) + { + T tmp_key; + R tmp_value; + if (pytype_traits_t::pyobj_to_cppobj(key, tmp_key) || + pytype_traits_t::pyobj_to_cppobj(value, tmp_value)) + { + return -1; + } + m_ret[tmp_key] = tmp_value; + } + return 0; + } + return -1; + } + static const char* get_typename() { return "std::map";} +}; + + +template +class pytype_tool_impl_t: public pytype_tool_t +{ +public: + pytype_tool_impl_t():m_ret(){} + + virtual int parse_value(PyObject *pvalue_) + { + if (pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret)) + { + return -1; + } + return 0; + } + + const T& get_value() const { return m_ret; } + virtual const char* return_type() {return pytype_traits_t::get_typename();} +private: + T m_ret; +}; + +template<> +class pytype_tool_impl_t: public pytype_tool_t +{ +public: + pytype_tool_impl_t():m_ret(){} + + virtual int parse_value(PyObject *pvalue_) + { + return 0; + } + + const cpp_void_t& get_value() const { return m_ret; } + virtual const char* return_type() { return "void";} +private: + cpp_void_t m_ret; +}; +template +class pytype_tool_impl_t: public pytype_tool_t +{ +public: + pytype_tool_impl_t():m_ret(){} + + virtual int parse_value(PyObject *pvalue_) + { + if (pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret)) + { + return -1; + } + return 0; + } + + T* get_value() const { return m_ret; } +private: + T* m_ret; +}; + + +template<> +class pytype_tool_impl_t: public pytype_tool_t +{ +public: + pytype_tool_impl_t():m_ret(){} + + virtual int parse_value(PyObject *pvalue_) + { + m_ret = pvalue_; + return 0; + } + + PyObject*& get_value() { return m_ret; } + bool need_release() { return false; } +private: + PyObject* m_ret; +}; + +#endif diff --git a/pyops_for_embed.h b/pyops_for_embed.h new file mode 100644 index 0000000..b87ebcf --- /dev/null +++ b/pyops_for_embed.h @@ -0,0 +1,77 @@ +#ifndef __PYOPS_FOR_EMBED +#define __PYOPS_FOR_EMBED + +#include "pyops_base.h" + + + + + +template +const T& pycall_t::call(const std::string& mod_name_, const std::string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) +{ + PyObject *pName = NULL, *pModule = NULL; + std::string err_msg; + + pName = PyString_FromString(mod_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return pyret.get_value(); + } + + call_func(pModule, mod_name_, func_name_, pyarg_, pyret, err_msg); + Py_DECREF(pModule); + + if (!err_msg.empty()) + { + throw runtime_error(err_msg.c_str()); + } + return pyret.get_value(); +} +template +const T& pycall_t::call_obj_method(PyObject *pObj, const std::string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) +{ + std::string err_msg; + if (NULL == pObj) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return pyret.get_value(); + } + + static std::string mod_name_ = "NaN"; + call_func(pObj, mod_name_, func_name_, pyarg_, pyret, err_msg); + + if (!err_msg.empty()) + { + throw runtime_error(err_msg.c_str()); + } + return pyret.get_value(); +} + +template +const T& pycall_t::call_lambda(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) +{ + std::string err_msg; + if (NULL == pFunc) + { + err_msg = "can not call null PyObject"; + throw runtime_error(err_msg.c_str()); + return pyret.get_value(); + } + + call_func_obj(pFunc, pyarg_, pyret, err_msg); + + if (!err_msg.empty()) + { + throw runtime_error(err_msg.c_str()); + } + return pyret.get_value(); +} + + +#endif diff --git a/pyops_for_extend.h b/pyops_for_extend.h new file mode 100644 index 0000000..59ec163 --- /dev/null +++ b/pyops_for_extend.h @@ -0,0 +1,1745 @@ +#ifndef __PYOPS_FOR_EXTEND_ +#define __PYOPS_FOR_EXTEND_ + +#include "pyops_base.h" + + + +//! 用于扩展python的工具类,用来解析参数 +struct pyext_tool_t +{ + pyext_tool_t(PyObject* args_): + m_args(args_), + m_arg_tuple(NULL), + m_index(0), + m_err(false), + m_func_addr(0) + { + if (!PyArg_ParseTuple(args_, "LO", &m_func_addr, &m_arg_tuple)) { + m_err = true; + return; + } + if (NULL == m_arg_tuple || false == PyTuple_Check(m_arg_tuple)) + { + PyErr_SetString(PyExc_TypeError, "arg type invalid(shoule func_name, args tuple)"); + m_err = true; + return; + } + m_size = PyTuple_Size(m_arg_tuple); + } + + template + pyext_tool_t& parse_arg(T& ret_arg_) + { + typedef typename type_ref_traits_t::value_t value_t; + if (false == m_err) + { + if (m_index >= m_size) + { + stringstream ss; + ss << "param num invalid, only["<< m_index + 1 <<"] provided"; + PyErr_SetString(PyExc_TypeError, ss.str().c_str()); + m_err = true; + return *this; + } + + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyTuple_GetItem(m_arg_tuple, m_index))) + { + stringstream ss; + ss << "param[" << m_index + 1 << "] type invalid, "<< pytype_traits_t::get_typename() << " needed"; + PyErr_SetString(PyExc_TypeError, ss.str().c_str()); + m_err = true; + return *this; + } + ++m_index; + ret_arg_ = ret_tool.get_value(); + } + return *this; + } + + bool is_err() const { return m_err;} + PTR_NUMBER get_func_addr() const { return m_func_addr;} + + template + FUNC get_func_ptr() const + { + FUNC f = NULL; + ::memcpy((void*)&f, (const void*)&m_func_addr, sizeof(m_func_addr)); + return f; + } + PyObject* m_args; + PyObject* m_arg_tuple; + int m_index; + int64_t m_size; + bool m_err;//! 是否异常 + int64_t m_func_addr; +}; + + + +//! 用于扩展python,生成pyobject类型的返回值给python +template +struct pyext_return_tool_t +{ + //! 用于静态方法 + template + static PyObject* route_call(F f) + { + return pytype_traits_t::pyobj_from_cppobj(f()); + } + template + static PyObject* route_call(F f, ARG1& a1) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value, a8.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value, a8.value, a9.value)); + } + //! 用于成员方法 + template + static PyObject* route_method_call(O o, F f) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)()); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value, a8.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value, a8.value, a9.value)); + } +}; + + +template<> +struct pyext_return_tool_t +{ + template + static PyObject* route_call(F f) + { + f(); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1) + { + f(a1.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2) + { + f(a1.value, a2.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3) + { + f(a1.value, a2.value, a3.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) + { + f(a1.value, a2.value, a3.value, a4.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f) + { + (o->*f)(); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1) + { + (o->*f)(a1.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2) + { + (o->*f)(a1.value, a2.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3) + { + (o->*f)(a1.value, a2.value, a3.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); + Py_RETURN_NONE; + } +}; + + + +//! 用于扩展python,traits出注册给python的函数接口 +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(); + static int args_num() { return 0;} + static int option_args_num() { return 0;} + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + return pyext_return_tool_t::route_call(f); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1); + static int args_num(){ return 1-option_args_num();} + static int option_args_num() + { + return pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + if (pyext_tool.parse_arg(a1.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2); + static int args_num() { return 2 - option_args_num();} + static int option_args_num() + { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3); + static int args_num() { return 3-option_args_num();} + static int option_args_num() + { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3); + } +}; +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4); + static int args_num() { return 4-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5); + static int args_num() { return 5-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); + static int args_num() { return 6-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); + static int args_num() { return 7-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); + static int args_num() { return 8-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7, a8); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); + static int args_num() { return 9-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + type_ref_traits_t a9; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7, a8, a9); + } +}; + + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + + self->obj = new CLASS_TYPE(); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + if (pyext_tool.parse_arg(a1.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + type_ref_traits_t a9; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); + return 0; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(); + static int args_num() { return 0;} + static int option_args_num() { return 0;} + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1); + static int args_num() { return 1-option_args_num();} + static int option_args_num() { return pyoption_traits_t::value_t>::is();} + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + if (pyext_tool.parse_arg(a1.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2); + static int args_num() { return 2-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2);; + } +}; + + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3); + static int args_num() { return 3-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4); + static int args_num() { return 4-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5); + static int args_num() { return 5-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); + static int args_num() { return 6-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); + static int args_num() { return 7-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); + static int args_num() { return 8-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8);; + } +}; + + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); + static int args_num() { return 9-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + type_ref_traits_t a9; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8, a9);; + } +}; + +//! const类型成员函数--------------------------------------------------------------------------------------------- + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)() const; + static int args_num() { return 0;} + static int option_args_num() { return 0;} + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1) const; + static int args_num() { return 1-option_args_num();} + static int option_args_num() { return pyoption_traits_t::value_t>::is();} + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + if (pyext_tool.parse_arg(a1.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2) const; + static int args_num() { return 2-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2);; + } +}; + + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3) const; + static int args_num() { return 3-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4) const; + static int args_num() { return 4-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5) const; + static int args_num() { return 5-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) const; + static int args_num() { return 6-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) const; + static int args_num() { return 7-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8) const; + static int args_num() { return 8-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8);; + } +}; + + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9) const; + static int args_num() { return 9-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + type_ref_traits_t a9; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8, a9);; + } +}; + + +#endif diff --git a/python2.7/VersionForRead/ffpython.cpp b/python2.7/VersionForRead/ffpython.cpp new file mode 100644 index 0000000..c78bf09 --- /dev/null +++ b/python2.7/VersionForRead/ffpython.cpp @@ -0,0 +1,568 @@ +#include "ffpython.h" + + +//! 获取python异常信息 + +int pyops_t::traceback(string& ret_) +{ + PyObject* err = PyErr_Occurred(); + + if (err != NULL) { + PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL; + PyObject *pyth_module = NULL, *pyth_func = NULL; + + PyErr_Fetch(&ptype, &pvalue, &ptraceback); + if (pvalue) + { + if (true == PyList_Check(pvalue)) + { + int n = PyList_Size(pvalue); + for (int i = 0; i < n; ++i) + { + PyObject *pystr = PyObject_Str(PyList_GetItem(pvalue, i)); + ret_ += PyString_AsString(pystr); + ret_ += "\n"; + Py_DECREF(pystr); + } + } + if (true == PyTuple_Check(pvalue)) + { + int n = PyTuple_Size(pvalue); + for (int i = 0; i < n; ++i) + { + PyObject* tmp_str = PyTuple_GetItem(pvalue, i); + if (true == PyTuple_Check(tmp_str)) + { + int m = PyTuple_Size(tmp_str); + for (int j = 0; j < m; ++j) + { + PyObject *pystr = PyObject_Str(PyTuple_GetItem(tmp_str, j)); + ret_ += PyString_AsString(pystr); + ret_ += ","; + Py_DECREF(pystr); + } + } + else + { + PyObject *pystr = PyObject_Str(tmp_str); + ret_ += PyString_AsString(pystr); + Py_DECREF(pystr); + } + ret_ += "\n"; + } + } + else + { + PyObject *pystr = PyObject_Str(pvalue); + if (pystr) + { + ret_ += PyString_AsString(pystr); + ret_ += "\n"; + Py_DECREF(pystr); + } + } + } + + /* See if we can get a full traceback */ + PyObject *module_name = PyString_FromString("traceback"); + pyth_module = PyImport_Import(module_name); + Py_DECREF(module_name); + + if (pyth_module && ptype && pvalue && ptraceback) + { + pyth_func = PyObject_GetAttrString(pyth_module, "format_exception"); + if (pyth_func && PyCallable_Check(pyth_func)) { + PyObject *pyth_val = PyObject_CallFunctionObjArgs(pyth_func, ptype, pvalue, ptraceback, NULL); + if (pyth_val && true == PyList_Check(pyth_val)) + { + int n = PyList_Size(pyth_val); + for (int i = 0; i < n; ++i) + { + PyObject* tmp_str = PyList_GetItem(pyth_val, i); + PyObject *pystr = PyObject_Str(tmp_str); + if (pystr) + { + ret_ += PyString_AsString(pystr); + + Py_DECREF(pystr); + } + ret_ += "\n"; + } + } + Py_XDECREF(pyth_val); + } + } + Py_XDECREF(pyth_func); + Py_XDECREF(pyth_module); + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + PyErr_Clear(); + return 0; + } + + return -1; +} + + +ffpython_t::ffpython_t() +{ + if (!Py_IsInitialized()) + Py_Initialize(); +} +ffpython_t::~ffpython_t() +{ + clear_cache_pyobject(); +} + + +int ffpython_t::init_py() +{ + Py_Initialize(); + return 0; +} +int ffpython_t::final_py() +{ + Py_Finalize(); + return 0; +} + +int ffpython_t::add_path(const string& path_) +{ + char buff[1024]; + SAFE_SPRINTF(buff, sizeof(buff), "import sys\nif '%s' not in sys.path:\n\tsys.path.append('%s')\n", path_.c_str(), path_.c_str()); + PyRun_SimpleString(buff); + return 0; +} + +int ffpython_t::run_string(const string& py_) +{ + PyRun_SimpleString(py_.c_str()); + return 0; +} + +int ffpython_t::reload(const string& py_name_) +{ + PyObject *pName = NULL, *pModule = NULL; + string err_msg; + + pName = PyString_FromString(py_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return -1; + } + + PyObject *pNewMod = PyImport_ReloadModule(pModule); + Py_DECREF(pModule); + if (NULL == pNewMod) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return -1; + } + Py_DECREF(pNewMod); + return 0; +} +int ffpython_t::load(const string& py_name_) +{ + PyObject *pName = NULL, *pModule = NULL; + string err_msg; + + pName = PyString_FromString(py_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return -1; + } + + Py_DECREF(pModule); + return 0; +} + +int ffpython_t::init(const string& mod_name_, string doc_) +{ + m_mod_name = mod_name_; + m_mod_doc = doc_; + PyObject* m = init_method(); + init_pyclass(m); + return 0; +} + +PyObject* ffpython_t::init_method() +{ + string mod_name_ = m_mod_name; + string doc_ = m_mod_doc; + + if (m_pymethod_defs.empty()) + { + m_pymethod_defs.reserve(m_func_info.size() + 1); + + for (size_t i = 0; i < m_func_info.size(); ++i) + { + PyMethodDef tmp = {m_func_info[i].func_impl_name.c_str(), m_func_info[i].func, + METH_VARARGS, m_func_info[i].doc_impl.c_str()}; + m_pymethod_defs.push_back(tmp); + } + PyMethodDef tmp = {NULL}; + m_pymethod_defs.push_back(tmp); + } + + PyObject* m = Py_InitModule3(m_mod_name.c_str(), &(m_pymethod_defs.front()), doc_.c_str()); + + for (size_t i = 0; i < m_func_info.size(); ++i) + { + string pystr_args; + string pystr_args_only_name; + for (int j = 0; j < m_func_info[i].args_num; ++j) + { + stringstream ss; + if (pystr_args.empty()) + { + ss << "a" << (j+1); + pystr_args += ss.str(); + } + else + { + ss << ", a" << (j+1); + pystr_args += ss.str(); + } + } + pystr_args_only_name = pystr_args; + for (int j = 0; j < m_func_info[i].option_args_num; ++j) + { + stringstream ss; + if (pystr_args.empty()) + { + ss << "a" << (m_func_info[i].args_num + j+1); + string tmp = ss.str(); + pystr_args_only_name += tmp; + pystr_args += tmp + " = None"; + } + else + { + ss << ", a" << (m_func_info[i].args_num + j+1); + string tmp = ss.str(); + pystr_args_only_name += tmp; + pystr_args += tmp + " = None"; + } + } + if (!pystr_args_only_name.empty()) + pystr_args_only_name += ","; + + char buff[1024]; + SAFE_SPRINTF(buff, sizeof(buff), + "_tmp_ff_ = None\nif '%s' in globals():\n\t_tmp_ff_ = globals()['%s']\n" + "def %s(%s):\n" + "\t'''%s'''\n" + "\treturn %s.%s(%ld,(%s))\n" + "import %s\n" + "%s.%s = %s\n" + "%s = None\n" + "if _tmp_ff_:\n\tglobals()['%s'] = _tmp_ff_\n_tmp_ff_ = None\n", + m_func_info[i].func_name.c_str(), m_func_info[i].func_name.c_str(), + m_func_info[i].func_name.c_str(), pystr_args.c_str(), + m_func_info[i].doc.c_str(), + m_mod_name.c_str(), m_func_info[i].func_impl_name.c_str(), m_func_info[i].func_addr, pystr_args_only_name.c_str(), + m_mod_name.c_str(), + m_mod_name.c_str(), m_func_info[i].func_name.c_str(), m_func_info[i].func_name.c_str(), + m_func_info[i].func_name.c_str(), + m_func_info[i].func_name.c_str() + ); + + //printf(buff); + PyRun_SimpleString(buff); + } + + return m; +} + +int ffpython_t::init_pyclass(PyObject* m) +{ + for (size_t i = 0; i < m_all_pyclass.size(); ++i) + { + m_all_pyclass[i].static_pytype_info->mod_name = m_mod_name; + if (false == m_all_pyclass[i].inherit_name.empty()) + { + pyclass_regigster_tool_t* inherit_class = get_pyclass_info_by_name(m_all_pyclass[i].inherit_name); + assert(inherit_class && "base class must be registed"); + for (size_t n = 0; n < inherit_class->methods_info.size(); ++n) + { + const string& method_name = inherit_class->methods_info[n].func_name; + if (false == is_method_exist(m_all_pyclass[i].methods_info, method_name)) + { + m_all_pyclass[i].methods_info.push_back(inherit_class->methods_info[n]); + } + } + for (size_t n = 0; n < inherit_class->propertys_info.size(); ++n) + { + const string& property_name = inherit_class->propertys_info[n].property_name; + if (false == is_property_exist(m_all_pyclass[i].propertys_info, property_name)) + { + m_all_pyclass[i].propertys_info.push_back(inherit_class->propertys_info[n]); + } + } + } + //! init class property + for (size_t j = 0; j < m_all_pyclass[i].propertys_info.size(); ++j) + { + PyGetSetDef tmp = {(char*)m_all_pyclass[i].propertys_info[j].property_name.c_str(), + m_all_pyclass[i].propertys_info[j].getter_func, + m_all_pyclass[i].propertys_info[j].setter_func, + (char*)m_all_pyclass[i].propertys_info[j].doc.c_str(), + m_all_pyclass[i].propertys_info[j].ptr + }; + m_all_pyclass[i].pyproperty_def.push_back(tmp); + } + PyGetSetDef tmp_property_def = {NULL}; + m_all_pyclass[i].pyproperty_def.push_back(tmp_property_def); + //! init class method + for (size_t j = 0; j < m_all_pyclass[i].methods_info.size(); ++j) + { + PyMethodDef tmp = {m_all_pyclass[i].methods_info[j].func_real_name.c_str(), + m_all_pyclass[i].methods_info[j].func, + METH_VARARGS, + m_all_pyclass[i].methods_info[j].doc.c_str() + }; + m_all_pyclass[i].pymethod_def.push_back(tmp); + + } + PyMethodDef tmp_del = {"delete", + m_all_pyclass[i].delete_func, + METH_VARARGS, + "delete obj" + }; + m_all_pyclass[i].pymethod_def.push_back(tmp_del); + PyMethodDef tmp_method_def = {NULL}; + m_all_pyclass[i].pymethod_def.push_back(tmp_method_def); + + m_all_pyclass[i].class_name_with_mod = m_mod_name + "." + m_all_pyclass[i].class_name; + m_all_pyclass[i].class_reel_name_with_mod = m_mod_name + "." + m_all_pyclass[i].class_real_name; + + PyTypeObject tmp_pytype_def = + { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + m_all_pyclass[i].class_reel_name_with_mod.c_str(), /*tp_name*/ + m_all_pyclass[i].type_size, /*tp_size*/ + 0, /*tp_itemsize*/ + (destructor)m_all_pyclass[i].dector, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + m_all_pyclass[i].doc.c_str(), /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + &(m_all_pyclass[i].pymethod_def.front()),//Noddy_methods, /* tp_methods */ + 0,//Noddy_members, /* tp_members */ + &(m_all_pyclass[i].pyproperty_def.front()),//Noddy_getseters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)m_all_pyclass[i].init, /* tp_init */ + 0, /* tp_alloc */ + m_all_pyclass[i].ctor, /* tp_new */ + }; + m_all_pyclass[i].pytype_def = tmp_pytype_def; + m_all_pyclass[i].static_pytype_info->pytype_def = &m_all_pyclass[i].pytype_def; + cpp_to_pyclass_reg_info_t::add(m_all_pyclass[i].class_name, m_all_pyclass[i].inherit_name, &m_all_pyclass[i].pytype_def); + + if (PyType_Ready(&(m_all_pyclass[i].pytype_def)) < 0) + return -1; + PyObject* tmpP = (PyObject*)(&(m_all_pyclass[i].pytype_def)); + Py_INCREF(tmpP); + PyModule_AddObject(m, m_all_pyclass[i].class_real_name.c_str(), (PyObject *)&m_all_pyclass[i].pytype_def); + + stringstream str_def_args; + stringstream str_init_args; + for (int a = 0; a < m_all_pyclass[i].args_num; ++a) + { + str_def_args << "a"<<(a+1)<<","; + str_init_args << "a"<<(a+1)<<","; + } + for (int b = 0; b < m_all_pyclass[b].option_args_num; ++b) + { + str_def_args << "a"<<(m_all_pyclass[i].args_num+ b+1)<<" = None,"; + str_init_args << "a"<<(m_all_pyclass[i].args_num+ b+1)<<","; + } + + char buff[1024]; + SAFE_SPRINTF(buff, sizeof(buff), + "_tmp_ff_ = None\nif '%s' in globals():\n\t_tmp_ff_ = globals()['%s']\n" + "import %s\n" + "class %s(object):\n" + "\t'''%s'''\n" + "\tdef __init__(self, %s assign_obj_ = 0):\n"//! ����init���� + "\t\t'''%s'''\n" + "\t\tif True == isinstance(assign_obj_, %s):\n" + "\t\t\tself.obj = assign_obj_\n" + "\t\t\treturn\n" + "\t\tself.obj = %s(0,(%s))\n", + m_all_pyclass[i].class_name.c_str(), m_all_pyclass[i].class_name.c_str(), + m_mod_name.c_str(), + m_all_pyclass[i].class_name.c_str(), + m_all_pyclass[i].doc.c_str(), + str_def_args.str().c_str(), + "init class", + m_all_pyclass[i].class_reel_name_with_mod.c_str(), + m_all_pyclass[i].class_reel_name_with_mod.c_str(), str_init_args.str().c_str() + ); + + string gen_class_str = buff; + SAFE_SPRINTF(buff, sizeof(buff), + "\tdef delete(self):\n" + "\t\t'''delete obj'''\n" + "\t\tself.obj.delete()\n"); + gen_class_str += buff; + //! 增加析构函数 + //! 增加属性 + for (size_t c = 0; c < m_all_pyclass[i].propertys_info.size(); ++c) + { + SAFE_SPRINTF(buff, sizeof(buff), + "\tdef get_%s(self):\n" + "\t\treturn self.obj.%s\n" + "\tdef set_%s(self, v):\n" + "\t\tself.obj.%s = v\n" + "\t@property\n" + "\tdef %s(self):\n" + "\t\treturn self.obj.%s\n" + "\t@%s.setter\n" + "\tdef %s(self, v):\n" + "\t\tself.obj.%s = v\n", + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str() + ); + gen_class_str += buff; + } + + for (size_t m = 0; m < m_all_pyclass[i].methods_info.size(); ++m) + { + string pystr_args; + string pystr_args_only_name; + for (int j = 0; j < m_all_pyclass[i].methods_info[m].args_num; ++j) + { + stringstream ss; + if (pystr_args.empty()) + { + ss << "a" << (j+1); + pystr_args += ss.str(); + } + else + { + ss << ", a" << (j+1); + pystr_args += ss.str(); + } + } + pystr_args_only_name = pystr_args; + for (int j = 0; j < m_all_pyclass[i].methods_info[m].option_args_num; ++j) + { + stringstream ss; + if (pystr_args.empty()) + { + ss << "a" << (m_all_pyclass[i].methods_info[m].args_num + j+1); + string tmp = ss.str(); + pystr_args_only_name += tmp; + pystr_args += tmp + " = None"; + } + else + { + ss << ", a" << (m_all_pyclass[i].methods_info[m].args_num + j+1); + string tmp = ss.str(); + pystr_args_only_name += tmp; + pystr_args += tmp + " = None"; + } + } + if (!pystr_args_only_name.empty()) + pystr_args_only_name += ","; + + SAFE_SPRINTF(buff, sizeof(buff), + "\tdef %s(self,%s):\n" + "\t\t'''%s'''\n" + "\t\treturn self.obj.%s(%ld,(%s))\n" + ,m_all_pyclass[i].methods_info[m].func_name.c_str(), pystr_args.c_str(), + m_all_pyclass[i].methods_info[m].doc.c_str(), + m_all_pyclass[i].methods_info[m].func_real_name.c_str(), m_all_pyclass[i].methods_info[m].func_addr, pystr_args_only_name.c_str() + ); + gen_class_str += buff; + } + SAFE_SPRINTF(buff, sizeof(buff), + "%s.%s = %s\n" + "%s = None\n" + "if _tmp_ff_:\n\tglobals()['%s'] = _tmp_ff_\n_tmp_ff_ = None\n", + m_mod_name.c_str(), m_all_pyclass[i].class_name.c_str(), m_all_pyclass[i].class_name.c_str(), + m_all_pyclass[i].class_name.c_str(), + m_all_pyclass[i].class_name.c_str() + ); + gen_class_str += buff; + //printf(gen_class_str.c_str()); + PyRun_SimpleString(gen_class_str.c_str()); + } + return 0; +} + + +bool ffpython_t::is_method_exist(const vector& src_, const string& new_) +{ + for (size_t i = 0; i < src_.size(); ++i) + { + if (new_ == src_[i].func_name) + { + return true; + } + } + return false; +} +bool ffpython_t::is_property_exist(const vector& src_, const string& new_) +{ + for (size_t i = 0; i < src_.size(); ++i) + { + if (new_ == src_[i].property_name) + { + return true; + } + } + return false; +} +pyclass_regigster_tool_t* ffpython_t::get_pyclass_info_by_name(const string& name_) +{ + for (size_t i = 0; i < m_all_pyclass.size(); ++i) + { + if (m_all_pyclass[i].class_name == name_) + { + return &(m_all_pyclass[i]); + } + } + return NULL; +} + diff --git a/python2.7/VersionForRead/ffpython.h b/python2.7/VersionForRead/ffpython.h new file mode 100644 index 0000000..5585f5f --- /dev/null +++ b/python2.7/VersionForRead/ffpython.h @@ -0,0 +1,481 @@ +#ifndef __FFPYTHON_H_ +#define __FFPYTHON_H_ + +#include +#include + +#include +using namespace std; + +#include "pyops_base.h" +#include "pyops_for_embed.h" +#include "pyops_for_extend.h" + +class ffpython_t +{ + struct reg_info_t + { + reg_info_t():args_num(0),option_args_num(0),func_addr(0){} + int args_num; + int option_args_num; + long func_addr; + PyCFunction func; + string func_name; + string func_impl_name; + string doc; + string doc_impl; + }; + +public: + ffpython_t(); + ~ffpython_t(); + + static int init_py(); + static int final_py(); + + static int add_path(const string& path_); + + static int run_string(const string& py_); + static int reload(const string& py_name_); + static int load(const string& py_name_); + + + //! 将需要注册的函数、类型注册到python虚拟机 + int init(const string& mod_name_, string doc_ = ""); + + //! 注册static function, + template + ffpython_t& reg(T func_, const string& func_name_, string doc_ = "") + { + reg_info_t tmp; + tmp.args_num = pyext_func_traits_t::args_num(); + tmp.option_args_num = pyext_func_traits_t::option_args_num(); + tmp.func = (PyCFunction)pyext_func_traits_t::pyfunc; + tmp.func_name= func_name_; + tmp.func_impl_name = func_name_ + "_internal_"; + tmp.doc = doc_; + tmp.doc_impl = string("internal use, please call ") + func_name_; + tmp.func_addr= (long)func_; + + m_func_info.push_back(tmp); + return *this; + } + + //! 注册c++ class + template + pyclass_regigster_tool_t& reg_class(const string& class_name_, string doc_ = "", string inherit_name_ = "") + { + if (pyclass_base_info_t::pytype_info.class_name.empty() == false) + throw runtime_error("this type has been registed"); + + pyclass_base_info_t::pytype_info.class_name = class_name_; + //pyclass_base_info_t::pytype_info.mod_name = m_mod_name; + pyclass_base_info_t::pytype_info.total_args_num = pyext_func_traits_t::args_num() + + pyext_func_traits_t::option_args_num(); + + pyclass_regigster_tool_t tmp; + tmp.class_name = class_name_; + tmp.class_real_name = class_name_ + "_internal_"; + tmp.inherit_name = inherit_name_; + tmp.doc = doc_; + tmp.dector = (destructor)pyclass_base_info_t::free_obj; + tmp.init = (initproc)pyclass_ctor_tool_t::init_obj; + tmp.ctor = pyclass_base_info_t::alloc_obj; + tmp.type_size = sizeof(typename pyclass_base_info_t::obj_data_t); + tmp.args_num = pyext_func_traits_t::args_num(); + tmp.option_args_num = pyext_func_traits_t::option_args_num(); + tmp.static_pytype_info = &(pyclass_base_info_t::pytype_info); + //! 注册析构函数,python若不调用析构函数,当对象被gc时自动调用 + tmp.delete_func = (PyCFunction)pyclass_base_info_t::release; + m_all_pyclass.push_back(tmp); + + return m_all_pyclass.back(); + } + + + //! 调用python函数,最多支持9个参数 + template + RET_V call(const string& mod_name_, const string& func_) + { + pycall_arg_t args(0); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1) + { + pycall_arg_t args(1); + args.add(a1); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2) + { + pycall_arg_t args(2); + args.add(a1).add(a2); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3) + { + pycall_arg_t args(3); + args.add(a1).add(a2).add(a3); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) + { + pycall_arg_t args(4); + args.add(a1).add(a2).add(a3).add(a4); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5) + { + pycall_arg_t args(5); + args.add(a1).add(a2).add(a3).add(a4).add(a5); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5,const ARG6& a6) + { + pycall_arg_t args(6); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5,const ARG6& a6,const ARG7& a7) + { + pycall_arg_t args(7); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) + { + pycall_arg_t args(8); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) + { + pycall_arg_t args(9); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8).add(a9); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + //!call python class method begin****************************************************************** + template + RET_V obj_call(PyObject* pobj, const string& func_) + { + pycall_arg_t args(0); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1) + { + pycall_arg_t args(1); + args.add(a1); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2) + { + pycall_arg_t args(2); + args.add(a1).add(a2); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3) + { + pycall_arg_t args(3); + args.add(a1).add(a2).add(a3); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) + { + pycall_arg_t args(4); + args.add(a1).add(a2).add(a3).add(a4); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5) + { + pycall_arg_t args(5); + args.add(a1).add(a2).add(a3).add(a4).add(a5); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5,const ARG6& a6) + { + pycall_arg_t args(6); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5,const ARG6& a6,const ARG7& a7) + { + pycall_arg_t args(7); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) + { + pycall_arg_t args(8); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) + { + pycall_arg_t args(9); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8).add(a9); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + //!call python class method end****************************************************************** + + //!call python lambad function begin ############################################################ + template + RET_V call_lambda(PyObject* pobj) + { + pycall_arg_t args(0); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1) + { + pycall_arg_t args(1); + args.add(a1); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2) + { + pycall_arg_t args(2); + args.add(a1).add(a2); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3) + { + pycall_arg_t args(3); + args.add(a1).add(a2).add(a3); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) + { + pycall_arg_t args(4); + args.add(a1).add(a2).add(a3).add(a4); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5) + { + pycall_arg_t args(5); + args.add(a1).add(a2).add(a3).add(a4).add(a5); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5,const ARG6& a6) + { + pycall_arg_t args(6); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5,const ARG6& a6,const ARG7& a7) + { + pycall_arg_t args(7); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) + { + pycall_arg_t args(8); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) + { + pycall_arg_t args(9); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8).add(a9); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + //!call python lambad function ennd ############################################################ + template + RET_V get_global_var(const string& mod_name_, const string& var_name_) + { + PyObject *pName = NULL, *pModule = NULL; + string err_msg; + + pName = PyString_FromString(mod_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + } + + pytype_tool_impl_t pyret; + PyObject *pvalue = PyObject_GetAttrString(pModule, var_name_.c_str()); + Py_DECREF(pModule); + + if (!pvalue) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + } + + if (pyret.parse_value(pvalue)) + { + Py_XDECREF(pvalue); + throw runtime_error("type invalid"); + } + Py_XDECREF(pvalue); + return pyret.get_value(); + } + + template + int set_global_var(const string& mod_name_, const string& var_name_, const T& val_) + { + PyObject *pName = NULL, *pModule = NULL; + string err_msg; + + pName = PyString_FromString(mod_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + } + + PyObject* pval = pytype_traits_t::pyobj_from_cppobj(val_); + int ret = PyObject_SetAttrString(pModule, var_name_.c_str(), pval); + Py_DECREF(pModule); + + return ret != -1? 0: -1; + } + + template + RET_V getattr(PyObject* pModule, const string& var_name_) + { + string err_msg; + if (NULL == pModule) + { + throw runtime_error("getattr object ptr null"); + } + + pytype_tool_impl_t pyret; + PyObject *pvalue = PyObject_GetAttrString(pModule, var_name_.c_str()); + + if (!pvalue) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + } + + if (pyret.parse_value(pvalue)) + { + Py_XDECREF(pvalue); + throw runtime_error("type invalid"); + } + Py_XDECREF(pvalue); + return pyret.get_value(); + } + + + void cache_pyobject(PyObject* pobj) + { + m_cache_pyobject.push_back(pobj); + } + void clear_cache_pyobject() + { + if (Py_IsInitialized()) + { + for (size_t i = 0; i < m_cache_pyobject.size(); ++i) + { + Py_XDECREF(m_cache_pyobject[i]); + } + m_cache_pyobject.clear(); + } + } +private: + PyObject* init_method(); + int init_pyclass(PyObject* m); + + + bool is_method_exist(const vector& src_, const string& new_); + bool is_property_exist(const vector& src_, const string& new_); + pyclass_regigster_tool_t* get_pyclass_info_by_name(const string& name_); + +private: + string m_mod_name; + string m_mod_doc; + vector m_pymethod_defs; + vector m_func_info; + + //! reg class + vector m_all_pyclass; + //! cache some pyobject for optimize + vector m_cache_pyobject; +}; + + +#endif diff --git a/python2.7/VersionForRead/pyops_base.h b/python2.7/VersionForRead/pyops_base.h new file mode 100644 index 0000000..ccb0f5c --- /dev/null +++ b/python2.7/VersionForRead/pyops_base.h @@ -0,0 +1,1123 @@ +#ifndef __PYOPS_BASE_ +#define __PYOPS_BASE_ + + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +using namespace std; + + +#ifdef _WIN32 +#define SAFE_SPRINTF _snprintf_s +#else +#define SAFE_SPRINTF snprintf +#endif + + + +//! 获取python异常信息 +struct pyops_t +{ + static int traceback(string& ret_); +}; +struct cpp_void_t{}; + +//! 用于抽取类型、类型对应的引用 +template +struct type_ref_traits_t; + +//! 用于python 可选参数 +template +struct pyoption_t +{ + typedef typename type_ref_traits_t::value_t value_t; + pyoption_t():m_set_flag(false){} + bool is_set() const { return m_set_flag;} + void set() { m_set_flag = true;} + value_t& value() { return m_value;} + const value_t& value() const{ return m_value;} + + const value_t& value(const value_t& default_) + { + if (is_set()) + return m_value; + else + return default_; + } + bool m_set_flag; + value_t m_value; +}; +//! 用于判断是否是可选参数 +template +struct pyoption_traits_t; + +//! pytype_traits_t 封装 PyLong_FromLong 相关的操作,用于为调用python生成参数 +template +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const char* const val_) + { + return PyString_FromString(val_); + } + /* + static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) + { + if (true == PyString_Check(pvalue_)) + { + m_ret = PyString_AsString(pvalue_); + return 0; + } + return -1; + } + */ + static const char* get_typename() { return "string";} +}; + +//! 用于调用python函数,生成tuple类型的python函数参数的工具类 +struct pycall_arg_t +{ + pycall_arg_t(int arg_num): + arg_index(0), + pargs_tuple(PyTuple_New(arg_num)) + {} + ~pycall_arg_t() + { + release(); + } + PyObject * get_args() const + { + return pargs_tuple; + } + template + pycall_arg_t& add(const T& val_) + { + if (arg_index < PyTuple_Size(pargs_tuple)) + { + PyObject* tmp_arg = pytype_traits_t::pyobj_from_cppobj(val_); + PyTuple_SetItem(pargs_tuple, arg_index, tmp_arg); + ++arg_index; + } + return *this; + } + void release() + { + if (pargs_tuple) + { + Py_DECREF(pargs_tuple); + pargs_tuple = NULL; + } + } + int arg_index; + PyObject * pargs_tuple; +}; + +//! 用于调用python函数,获取返回值的工具类 +class pytype_tool_t +{ +public: + virtual ~pytype_tool_t(){}; + virtual int parse_value(PyObject *pvalue_) = 0; + virtual const char* return_type() {return "";} + virtual bool need_release() { return false; } +}; + +//! 用于调用python函数,获取返回值的工具泛型类 +template +class pytype_tool_impl_t; +//! 封装调用python函数的C API +struct pycall_t +{ + static int call_func(PyObject *pModule, const string& mod_name_, const string& func_name_, + pycall_arg_t& pyarg_, pytype_tool_t& pyret_, string& err_) + { + PyObject *pFunc = PyObject_GetAttrString(pModule, func_name_.c_str()); + if (pFunc && PyCallable_Check(pFunc)) { + PyObject *pArgs = pyarg_.get_args(); + PyObject *pValue = PyObject_CallObject(pFunc, pArgs); + pyarg_.release();//! 等价于Py_DECREF(pArgs); + + if (pValue != NULL) { + if (pyret_.parse_value(pValue)) + { + err_ += "value returned is not "; + err_ += pyret_.return_type(); + err_ += string(" ") + func_name_ + " in " + mod_name_; + } + if (pyret_.need_release()){ + Py_DECREF(pValue); + } + } + } + else + { + err_ += "Cannot find function "; + err_ += func_name_ + " in " + mod_name_ + ","; + } + + Py_XDECREF(pFunc); + if (PyErr_Occurred()) + { + pyops_t::traceback(err_); + return 0; + } + return 0; + } + static int call_func_obj(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_t& pyret_, string& err_) + { + if (pFunc && PyCallable_Check(pFunc)) { + PyObject *pArgs = pyarg_.get_args(); + PyObject *pValue = PyObject_CallObject(pFunc, pArgs); + pyarg_.release();//! 等价于Py_DECREF(pArgs); + + if (pValue != NULL) { + if (pyret_.parse_value(pValue)) + { + err_ += "value returned is not "; + err_ += pyret_.return_type(); + } + if (pyret_.need_release()){ + Py_DECREF(pValue); + } + } + } + else + { + err_ += "invalid function"; + } + + if (PyErr_Occurred()) + { + pyops_t::traceback(err_); + return 0; + } + return 0; + } + template + static const T& call(const string& mod_name_, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); + template + static const T& call_obj_method(PyObject *pObj, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); + template + static const T& call_lambda(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); +}; +//! 用于扩展python的工具类,用来解析参数 +struct pyext_tool_t; + + +template +struct pyext_return_tool_t; + +//! 用于扩展python,生成pyobject类型的返回值给python +template +struct pyext_func_traits_t; + +//! 用于扩展python,traits出注册给python的函数接口 +#ifndef PYCTOR +#define PYCTOR int (*) +#endif +//! 表示void类型,由于void类型不能return,用void_ignore_t适配 +template +struct void_ignore_t; + +template +struct void_ignore_t +{ + typedef T value_t; +}; + +template<> +struct void_ignore_t +{ + typedef cpp_void_t value_t; +}; + +#define RET_V typename void_ignore_t::value_t + +//! 记录各个基类和子类的相互关系 +struct cpp_to_pyclass_reg_info_t +{ + struct inherit_info_t + { + inherit_info_t():pytype_def(NULL){} + PyTypeObject* pytype_def; + string inherit_name; + set all_child; + }; + typedef map inherit_info_map_t; + static inherit_info_map_t& get_all_info() + { + static inherit_info_map_t inherit_info; + return inherit_info; + } + + static void add(const string& child_, const string& base_, PyTypeObject* def_) + { + inherit_info_t tmp; + tmp.inherit_name = base_; + tmp.pytype_def = def_; + get_all_info()[child_] = tmp; + get_all_info()[base_].all_child.insert(def_); + } + static bool is_instance(PyObject* pysrc, const string& class_) + { + inherit_info_map_t& inherit_info = get_all_info(); + inherit_info_t& tmp = inherit_info[class_]; + if (tmp.pytype_def && PyObject_TypeCheck(pysrc, tmp.pytype_def)) + { + return true; + } + for (set::iterator it = tmp.all_child.begin(); it != tmp.all_child.end(); ++it) + { + if (*it && PyObject_TypeCheck(pysrc, *it)) + { + return true; + } + } + + return false; + } + +}; + + +//! 记录C++ class 对应到python中的名称、参数信息等,全局 +struct static_pytype_info_t +{ + string class_name; + string mod_name; + int total_args_num; + PyTypeObject* pytype_def; +}; + +//! 工具类,用于生成分配python class的接口,包括分配、释放 +template +struct pyclass_base_info_t +{ + struct obj_data_t + { + obj_data_t():obj(NULL){} + + PyObject_HEAD; + T* obj; + bool forbid_release; + void disable_auto_release(){ forbid_release = true; } + void release() + { + if (obj) + { + delete obj; + obj = NULL; + } + } + }; + + static void free_obj(obj_data_t* self) + { + if (false == self->forbid_release && self->obj) + { + self->release(); + } + self->ob_type->tp_free((PyObject*)self); + } + + static PyObject *alloc_obj(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + obj_data_t *self = (obj_data_t *)type->tp_alloc(type, 0); + return (PyObject *)self; + } + static PyObject *release(PyTypeObject *type, PyObject *args) + { + obj_data_t *self = (obj_data_t *)type; + self->release(); + return Py_BuildValue("i", 1); + } + static static_pytype_info_t pytype_info; +}; +template +static_pytype_info_t pyclass_base_info_t::pytype_info; + +//! 方便生成pyclass 初始化函数 +template +struct pyclass_ctor_tool_t; + +//! used to gen method of py class +template +struct pyclass_method_gen_t; + +//! 防止出现指针为NULL调用出错 +#define NULL_PTR_GUARD(X) if (NULL == X) {PyErr_SetString(PyExc_TypeError, "obj data ptr NULL");return NULL;} + +//! 用于生成python 的getter和setter接口,适配于c++ class的成员变量 +template +struct pyclass_member_func_gen_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + typedef RET CLASS_TYPE::* property_ptr_t; + + static PyObject *getter_func(obj_data_t *self, void *closure) + { + property_ptr_t property_ptr; + ::memcpy((void*)&property_ptr, (const void*)&closure, sizeof(closure)); + NULL_PTR_GUARD(self->obj); + CLASS_TYPE* p = self->obj; + return pytype_traits_t::pyobj_from_cppobj(p->*property_ptr); + } + static int setter_func(obj_data_t *self, PyObject *value, void *closure) + { + property_ptr_t property_ptr; + ::memcpy((void*)&property_ptr, (const void*)&closure, sizeof(closure)); + CLASS_TYPE* p = self->obj; + + return pytype_traits_t::pyobj_to_cppobj(value, p->*property_ptr); + } +}; + +//! 用于C++ 注册class的工具类,会记录class对应的名称、成员方法、成员变量 +class pyclass_regigster_tool_t +{ +public: + struct method_info_t + { + PyCFunction func; + string func_name; + string func_real_name; + string doc; + string doc_real; + int args_num; + int option_args_num; + long func_addr; + }; + struct property_info_t + { + void* ptr; + string property_name; + string doc; + getter getter_func; + setter setter_func; + }; + virtual ~pyclass_regigster_tool_t(){} + + typedef PyObject *(*pyobj_alloc_t)(PyTypeObject*, PyObject*, PyObject*); + + string class_name; + string class_real_name; + string class_name_with_mod; + string class_reel_name_with_mod; + string inherit_name; + int type_size; + string doc; + int args_num; + int option_args_num; + destructor dector; + initproc init; + pyobj_alloc_t ctor; + + //! member functions + PyCFunction delete_func; + vector methods_info; + //! property + vector propertys_info; + //! for init module + PyTypeObject pytype_def; + //! method + vector pymethod_def; + //! property + vector pyproperty_def; + + //! 静态类型需要全局记录该类型被注册成神马python 类型 + static_pytype_info_t* static_pytype_info; + + template + pyclass_regigster_tool_t& reg(FUNC f_, const string& func_name_, string doc_ = "") + { + method_info_t tmp; + tmp.func_name = func_name_; + tmp.func_real_name = func_name_ + "_internal_"; + tmp.doc = doc_; + tmp.doc_real = "internal use"; + tmp.func = (PyCFunction)pyclass_method_gen_t::pymethod; + tmp.args_num = pyclass_method_gen_t::args_num(); + tmp.option_args_num = pyclass_method_gen_t::option_args_num(); + ::memcpy((void*)&tmp.func_addr, (const void*)&f_, sizeof(void*)); + methods_info.push_back(tmp); + return *this; + } + template + pyclass_regigster_tool_t& reg_property(RET CLASS_TYPE::* member_, const string& member_name_, string doc_ = "") + { + property_info_t tmp; + ::memcpy((void*)&tmp.ptr, (const void*)&member_, sizeof(member_)); + tmp.property_name = member_name_; + tmp.doc = doc_; + tmp.getter_func = (getter)pyclass_member_func_gen_t::getter_func; + tmp.setter_func = (setter)pyclass_member_func_gen_t::setter_func; + propertys_info.push_back(tmp); + return *this; + } +}; + + +template +struct type_ref_traits_t +{ + typedef T value_t; + typedef T& ref_t; + value_t value; +}; +template +struct type_ref_traits_t +{ + typedef T value_t; + typedef T& ref_t; + value_t value; +}; +template +struct type_ref_traits_t +{ + typedef T value_t; + typedef T& ref_t; + value_t value; +}; +//! 用于判断是否是可选参数 +template +struct pyoption_traits_t +{ + static int is() { return 0;} +}; +template +struct pyoption_traits_t > +{ + static int is() { return 1;} +}; + + +template<>//typename T> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const long& val_) + { + return PyLong_FromLong(long(val_)); + } + static int pyobj_to_cppobj(PyObject *pvalue_, long& m_ret) + { + if (true == PyLong_Check(pvalue_)) + { + m_ret = (long)PyLong_AsLong(pvalue_); + return 0; + } + else if (true == PyInt_Check(pvalue_)) + { + m_ret = (long)PyInt_AsLong(pvalue_); + return 0; + } + return -1; + } + static const char* get_typename() { return "long";} +}; + +#define IMPL_INT_CODE(X) \ +template<> \ +struct pytype_traits_t \ +{ \ + static PyObject* pyobj_from_cppobj(const X& val_) \ + { \ + return PyInt_FromLong(long(val_)); \ + } \ + static int pyobj_to_cppobj(PyObject *pvalue_, X& m_ret) \ + { \ + if (true == PyLong_Check(pvalue_)) \ + { \ + m_ret = (X)PyLong_AsLong(pvalue_); \ + return 0; \ + } \ + else if (true == PyInt_Check(pvalue_)) \ + { \ + m_ret = (X)PyInt_AsLong(pvalue_); \ + return 0; \ + } \ + return -1; \ + } \ + static const char* get_typename() { return #X;} \ +}; + +IMPL_INT_CODE(int) +IMPL_INT_CODE(unsigned int) +IMPL_INT_CODE(short) +IMPL_INT_CODE(unsigned short) +IMPL_INT_CODE(char) +IMPL_INT_CODE(unsigned char) + +#ifdef _WIN32 +IMPL_INT_CODE(unsigned long) +#else +#ifndef __x86_64__ +IMPL_INT_CODE(int64_t) +#endif +IMPL_INT_CODE(uint64_t) +#endif + +template +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const T* val_) + { + const string& mod_name = pyclass_base_info_t::pytype_info.mod_name; + const string& class_name = pyclass_base_info_t::pytype_info.class_name; + PyObject *pName = NULL, *pModule = NULL, *pValue = NULL; + + if (class_name.empty()) + return pytype_traits_t::pyobj_from_cppobj(long(val_)); + + pName = PyString_FromString(mod_name.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + if (PyErr_Occurred()) + PyErr_Print(); + fprintf(stderr, "Failed to load \"%s\"\n", mod_name.c_str()); + assert(NULL && "this can not be happened"); + return NULL; + } + PyObject *pyclass = PyObject_GetAttrString(pModule, class_name.c_str()); + if (pyclass && PyCallable_Check(pyclass)) { + PyObject *pArgs = PyTuple_New(pyclass_base_info_t::pytype_info.total_args_num+1); + for (int i = 0; i< pyclass_base_info_t::pytype_info.total_args_num; ++i) + { + PyTuple_SetItem(pArgs, i, pytype_traits_t::pyobj_from_cppobj(0)); + } + + PyObject *palloc = pyclass_base_info_t::alloc_obj(pyclass_base_info_t::pytype_info.pytype_def, NULL, NULL); + typename pyclass_base_info_t::obj_data_t* pdest_obj = (typename pyclass_base_info_t::obj_data_t*)palloc; + //pdest_obj->obj = val_; + ::memcpy((void*)&pdest_obj->obj, (const void*)&val_, sizeof(pdest_obj->obj)); + pdest_obj->disable_auto_release(); + PyTuple_SetItem(pArgs, pyclass_base_info_t::pytype_info.total_args_num, palloc); + pValue = PyObject_CallObject(pyclass, pArgs); + Py_XDECREF(pArgs); + } + + Py_XDECREF(pyclass); + Py_DECREF(pModule); + return pValue; + } + + static int pyobj_to_cppobj(PyObject *pvalue_, T*& m_ret) + { + PyObject *pysrc = PyObject_GetAttrString(pvalue_, "obj"); + //!PyObject_TypeCheck(pysrc, pyclass_base_info_t::pytype_info.pytype_def)) { + if (NULL == pysrc || false == cpp_to_pyclass_reg_info_t::is_instance(pysrc, pyclass_base_info_t::pytype_info.class_name)) + { + Py_XDECREF(pysrc); + return -1; + } + typename pyclass_base_info_t::obj_data_t* pdest_obj = (typename pyclass_base_info_t::obj_data_t*)pysrc; + + m_ret = pdest_obj->obj; + Py_XDECREF(pysrc); + return 0; + } + + static const char* get_typename() { return pyclass_base_info_t::pytype_info.class_name.c_str();} +}; + +template +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(T* val_) + { + return pytype_traits_t::pyobj_from_cppobj(val_); + } + static int pyobj_to_cppobj(PyObject *pvalue_,T*& m_ret) + { + return pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret); + } + static const char* get_typename() { return pyclass_base_info_t::pytype_info.class_name.c_str();} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(PyObject* val_) + { + return val_; + } + static int pyobj_to_cppobj(PyObject *pvalue_, PyObject*& m_ret) + { + m_ret = pvalue_; + return 0; + } + static const char* get_typename() { return "PyObject";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const char* const val_) + { + return PyString_FromString(val_); + } + /* + static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) + { + if (true == PyString_Check(pvalue_)) + { + m_ret = PyString_AsString(pvalue_); + return 0; + } + return -1; + } + */ + static const char* get_typename() { return "string";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const char*& val_) + { + return PyString_FromString(val_); + } + /* + static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) + { + if (true == PyString_Check(pvalue_)) + { + m_ret = PyString_AsString(pvalue_); + return 0; + } + return -1; + } + */ + static const char* get_typename() { return "string";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(bool val_) + { + if (val_) + { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; + } + static int pyobj_to_cppobj(PyObject *pvalue_, bool& m_ret) + { + if (Py_False == pvalue_|| Py_None == pvalue_) + { + m_ret = false; + } + else + { + m_ret = true; + } + return 0; + } + static const char* get_typename() { return "bool";} +}; + +template +struct pytype_traits_t > +{ + static int pyobj_to_cppobj(PyObject *pvalue_, pyoption_t& m_ret) + { + if (Py_None == pvalue_) + { + return 0; + } + else if (0 == pytype_traits_t::value_t>::pyobj_to_cppobj(pvalue_, m_ret.value())) + { + m_ret.set(); + return 0; + } + return -1; + } + static const char* get_typename() { return "pyoption_t";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const string& val_) + { + return PyString_FromStringAndSize(val_.c_str(), val_.size()); + } + static int pyobj_to_cppobj(PyObject *pvalue_, string& m_ret) + { + if (true == PyString_Check(pvalue_)) + { + char* pDest = NULL; + Py_ssize_t nLen = 0; + PyString_AsStringAndSize(pvalue_, &pDest, &nLen); + + m_ret.assign(pDest, nLen); + return 0; + } + else if (true == PyUnicode_Check(pvalue_)) + { + char* pDest = NULL; + Py_ssize_t nLen = 0; + PyString_AsStringAndSize(pvalue_, &pDest, &nLen); + m_ret.assign(pDest, nLen); + return 0; + /* +#ifdef _WIN32 + PyObject* retStr = PyUnicode_AsEncodedString(pvalue_, "gbk", ""); +#else + PyObject* retStr = PyUnicode_AsUTF8String(pvalue_); +#endif + if (retStr) + { + m_ret = PyString_AsString(retStr); + Py_XDECREF(retStr); + return 0; + } + */ + } + return -1; + } + static const char* get_typename() { return "string";} +}; + +#ifdef _WIN32 +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const wstring& wstr) + { + return PyUnicode_FromWideChar(wstr.c_str(), wstr.length()); + } + static int pyobj_to_cppobj(PyObject *pvalue_, wstring& wstr_ret) + { + if (true == PyString_Check(pvalue_)) + { + PyObject* retStr = PyUnicode_FromObject(pvalue_); + if (retStr) + { + int n = PyUnicode_GetSize(retStr); + wstr_ret.resize(n); + n = PyUnicode_AsWideChar((PyUnicodeObject*)retStr, &(wstr_ret[0]), n); + Py_XDECREF(retStr); + return 0; + } + return 0; + } + else if (true == PyUnicode_Check(pvalue_)) + { + int n = PyUnicode_GetSize(pvalue_); + wstr_ret.resize(n); + n = PyUnicode_AsWideChar((PyUnicodeObject*)pvalue_, &(wstr_ret[0]), n); + return 0; + } + return -1; + } + static const char* get_typename() { return "wstring";} +}; +#endif + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(float val_) + { + return PyFloat_FromDouble(double(val_)); + } + static int pyobj_to_cppobj(PyObject *pvalue_, float& m_ret) + { + if (true == PyFloat_Check(pvalue_)) + { + m_ret = (float)PyFloat_AsDouble(pvalue_); + return 0; + } + return -1; + } + static const char* get_typename() { return "float";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(double val_) + { + return PyFloat_FromDouble(val_); + } + static int pyobj_to_cppobj(PyObject *pvalue_, double& m_ret) + { + if (true == PyFloat_Check(pvalue_)) + { + m_ret = PyFloat_AsDouble(pvalue_); + return 0; + } + return -1; + } + static const char* get_typename() { return "double";} +}; + +template +struct pytype_traits_t > +{ + static PyObject* pyobj_from_cppobj(const vector& val_) + { + PyObject* ret = PyList_New(val_.size()); + for (size_t i = 0; i < val_.size(); ++i) + { + PyList_SetItem(ret, i, pytype_traits_t::pyobj_from_cppobj(val_[i])); + } + return ret; + } + static int pyobj_to_cppobj(PyObject *pvalue_, vector& m_ret) + { + m_ret.clear(); + if (true == PyTuple_Check(pvalue_)) + { + int n = PyTuple_Size(pvalue_); + for (int i = 0; i < n; ++i) + { + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyTuple_GetItem(pvalue_, i))) + { + return -1; + } + m_ret.push_back(ret_tool.get_value()); + } + return 0; + } + else if (true == PyList_Check(pvalue_)) + { + int n = PyList_Size(pvalue_); + for (int i = 0; i < n; ++i) + { + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyList_GetItem(pvalue_, i))) + { + return -1; + } + m_ret.push_back(ret_tool.get_value()); + } + return 0; + } + return -1; + } + static const char* get_typename() { return "vector";} +}; +template +struct pytype_traits_t > +{ + static PyObject* pyobj_from_cppobj(const list& val_) + { + size_t n = val_.size(); + PyObject* ret = PyList_New(n); + int i = 0; + for (typename list::const_iterator it = val_.begin(); it != val_.end(); ++it) + { + PyList_SetItem(ret, i++, pytype_traits_t::pyobj_from_cppobj(*it)); + } + return ret; + } + static int pyobj_to_cppobj(PyObject *pvalue_, list& m_ret) + { + pytype_tool_impl_t ret_tool; + if (true == PyTuple_Check(pvalue_)) + { + int n = PyTuple_Size(pvalue_); + for (int i = 0; i < n; ++i) + { + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyTuple_GetItem(pvalue_, i))) + { + return -1; + } + m_ret.push_back(ret_tool.get_value()); + } + return 0; + } + else if (true == PyList_Check(pvalue_)) + { + int n = PyList_Size(pvalue_); + for (int i = 0; i < n; ++i) + { + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyList_GetItem(pvalue_, i))) + { + return -1; + } + m_ret.push_back(ret_tool.get_value()); + } + return 0; + } + return -1; + } + static const char* get_typename() { return "list";} +}; +template +struct pytype_traits_t > +{ + static PyObject* pyobj_from_cppobj(const set& val_) + { + PyObject* ret = PySet_New(NULL); + for (typename set::const_iterator it = val_.begin(); it != val_.end(); ++it) + { + PyObject *v = pytype_traits_t::pyobj_from_cppobj(*it); + PySet_Add(ret, v); + Py_DECREF(v); + } + return ret; + } + static int pyobj_to_cppobj(PyObject *pvalue_, set& m_ret) + { + m_ret.clear(); + pytype_tool_impl_t ret_tool; + PyObject *iter = PyObject_GetIter(pvalue_); + PyObject *item = NULL; + while (NULL != iter && NULL != (item = PyIter_Next(iter))) + { + T tmp(); + if (pytype_traits_t::pyobj_to_cppobj(item, tmp)) + { + Py_DECREF(item); + Py_DECREF(iter); + return -1; + } + m_ret.insert(tmp); + Py_DECREF(item); + } + if (iter) + { + Py_DECREF(iter); + return 0; + } + return -1; + } + static const char* get_typename() { return "set";} +}; +template +struct pytype_traits_t > +{ + static PyObject* pyobj_from_cppobj(const map& val_) + { + PyObject* ret = PyDict_New(); + for (typename map::const_iterator it = val_.begin(); it != val_.end(); ++it) + { + PyObject *k = pytype_traits_t::pyobj_from_cppobj(it->first); + PyObject *v = pytype_traits_t::pyobj_from_cppobj(it->second); + PyDict_SetItem(ret, k, v); + Py_DECREF(k); + Py_DECREF(v); + } + return ret; + } + static int pyobj_to_cppobj(PyObject *pvalue_, map& m_ret) + { + m_ret.clear(); + pytype_tool_impl_t ret_tool_T; + pytype_tool_impl_t ret_tool_R; + if (true == PyDict_Check(pvalue_)) + { + PyObject *key = NULL, *value = NULL; + Py_ssize_t pos = 0; + + while (PyDict_Next(pvalue_, &pos, &key, &value)) + { + T tmp_key; + R tmp_value; + if (pytype_traits_t::pyobj_to_cppobj(key, tmp_key) || + pytype_traits_t::pyobj_to_cppobj(value, tmp_value)) + { + return -1; + } + m_ret[tmp_key] = tmp_value; + } + return 0; + } + return -1; + } + static const char* get_typename() { return "map";} +}; + +//! ��ȡpython�����ķ���ֵ,������ +template +class pytype_tool_impl_t: public pytype_tool_t +{ +public: + pytype_tool_impl_t():m_ret(){} + + virtual int parse_value(PyObject *pvalue_) + { + if (pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret)) + { + return -1; + } + return 0; + } + + const T& get_value() const { return m_ret; } + virtual const char* return_type() {return pytype_traits_t::get_typename();} +private: + T m_ret; +}; + +template<> +class pytype_tool_impl_t: public pytype_tool_t +{ +public: + pytype_tool_impl_t():m_ret(){} + + virtual int parse_value(PyObject *pvalue_) + { + return 0; + } + + const cpp_void_t& get_value() const { return m_ret; } + virtual const char* return_type() { return "void";} +private: + cpp_void_t m_ret; +}; +template +class pytype_tool_impl_t: public pytype_tool_t +{ +public: + pytype_tool_impl_t():m_ret(){} + + virtual int parse_value(PyObject *pvalue_) + { + if (pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret)) + { + return -1; + } + return 0; + } + + T* get_value() const { return m_ret; } +private: + T* m_ret; +}; + + +template<> +class pytype_tool_impl_t: public pytype_tool_t +{ +public: + pytype_tool_impl_t():m_ret(){} + + virtual int parse_value(PyObject *pvalue_) + { + m_ret = pvalue_; + return 0; + } + + PyObject*& get_value() { return m_ret; } + bool need_release() { return false; } +private: + PyObject* m_ret; +}; + +#endif diff --git a/python2.7/VersionForRead/pyops_for_embed.h b/python2.7/VersionForRead/pyops_for_embed.h new file mode 100644 index 0000000..e91a7f3 --- /dev/null +++ b/python2.7/VersionForRead/pyops_for_embed.h @@ -0,0 +1,77 @@ +#ifndef __PYOPS_FOR_EMBED +#define __PYOPS_FOR_EMBED + +#include "pyops_base.h" + + + + + +template +const T& pycall_t::call(const string& mod_name_, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) +{ + PyObject *pName = NULL, *pModule = NULL; + string err_msg; + + pName = PyString_FromString(mod_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return pyret.get_value(); + } + + call_func(pModule, mod_name_, func_name_, pyarg_, pyret, err_msg); + Py_DECREF(pModule); + + if (!err_msg.empty()) + { + throw runtime_error(err_msg.c_str()); + } + return pyret.get_value(); +} +template +const T& pycall_t::call_obj_method(PyObject *pObj, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) +{ + string err_msg; + if (NULL == pObj) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return pyret.get_value(); + } + + static string mod_name_ = "NaN"; + call_func(pObj, mod_name_, func_name_, pyarg_, pyret, err_msg); + + if (!err_msg.empty()) + { + throw runtime_error(err_msg.c_str()); + } + return pyret.get_value(); +} + +template +const T& pycall_t::call_lambda(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) +{ + string err_msg; + if (NULL == pFunc) + { + err_msg = "can not call null PyObject"; + throw runtime_error(err_msg.c_str()); + return pyret.get_value(); + } + + call_func_obj(pFunc, pyarg_, pyret, err_msg); + + if (!err_msg.empty()) + { + throw runtime_error(err_msg.c_str()); + } + return pyret.get_value(); +} + + +#endif diff --git a/python2.7/VersionForRead/pyops_for_extend.h b/python2.7/VersionForRead/pyops_for_extend.h new file mode 100644 index 0000000..e91ca90 --- /dev/null +++ b/python2.7/VersionForRead/pyops_for_extend.h @@ -0,0 +1,1745 @@ +#ifndef __PYOPS_FOR_EXTEND_ +#define __PYOPS_FOR_EXTEND_ + +#include "pyops_base.h" + + + +//! 用于扩展python的工具类,用来解析参数 +struct pyext_tool_t +{ + pyext_tool_t(PyObject* args_): + m_args(args_), + m_arg_tuple(NULL), + m_index(0), + m_err(false), + m_func_addr(0) + { + if (!PyArg_ParseTuple(args_, "lO", &m_func_addr, &m_arg_tuple)) { + m_err = true; + return; + } + if (NULL == m_arg_tuple || false == PyTuple_Check(m_arg_tuple)) + { + PyErr_SetString(PyExc_TypeError, "arg type invalid(shoule func_name, args tuple)"); + m_err = true; + return; + } + m_size = PyTuple_Size(m_arg_tuple); + } + + template + pyext_tool_t& parse_arg(T& ret_arg_) + { + typedef typename type_ref_traits_t::value_t value_t; + if (false == m_err) + { + if (m_index >= m_size) + { + stringstream ss; + ss << "param num invalid, only["<< m_index + 1 <<"] provided"; + PyErr_SetString(PyExc_TypeError, ss.str().c_str()); + m_err = true; + return *this; + } + + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyTuple_GetItem(m_arg_tuple, m_index))) + { + stringstream ss; + ss << "param[" << m_index + 1 << "] type invalid, "<< pytype_traits_t::get_typename() << " needed"; + PyErr_SetString(PyExc_TypeError, ss.str().c_str()); + m_err = true; + return *this; + } + ++m_index; + ret_arg_ = ret_tool.get_value(); + } + return *this; + } + + bool is_err() const { return m_err;} + long get_func_addr() const { return m_func_addr;} + + template + FUNC get_func_ptr() const + { + FUNC f = NULL; + ::memcpy((void*)&f, (const void*)&m_func_addr, sizeof(m_func_addr)); + return f; + } + PyObject* m_args; + PyObject* m_arg_tuple; + int m_index; + int m_size; + bool m_err;//! 是否异常 + long m_func_addr; +}; + + + +//! 用于扩展python,生成pyobject类型的返回值给python +template +struct pyext_return_tool_t +{ + //! 用于静态方法 + template + static PyObject* route_call(F f) + { + return pytype_traits_t::pyobj_from_cppobj(f()); + } + template + static PyObject* route_call(F f, ARG1& a1) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value, a8.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value, a8.value, a9.value)); + } + //! 用于成员方法 + template + static PyObject* route_method_call(O o, F f) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)()); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value, a8.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value, a8.value, a9.value)); + } +}; + + +template<> +struct pyext_return_tool_t +{ + template + static PyObject* route_call(F f) + { + f(); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1) + { + f(a1.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2) + { + f(a1.value, a2.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3) + { + f(a1.value, a2.value, a3.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) + { + f(a1.value, a2.value, a3.value, a4.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f) + { + (o->*f)(); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1) + { + (o->*f)(a1.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2) + { + (o->*f)(a1.value, a2.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3) + { + (o->*f)(a1.value, a2.value, a3.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); + Py_RETURN_NONE; + } +}; + + + +//! 用于扩展python,traits出注册给python的函数接口 +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(); + static int args_num() { return 0;} + static int option_args_num() { return 0;} + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + return pyext_return_tool_t::route_call(f); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1); + static int args_num(){ return 1-option_args_num();} + static int option_args_num() + { + return pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + if (pyext_tool.parse_arg(a1.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2); + static int args_num() { return 2 - option_args_num();} + static int option_args_num() + { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3); + static int args_num() { return 3-option_args_num();} + static int option_args_num() + { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3); + } +}; +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4); + static int args_num() { return 4-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5); + static int args_num() { return 5-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); + static int args_num() { return 6-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); + static int args_num() { return 7-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); + static int args_num() { return 8-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7, a8); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); + static int args_num() { return 9-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + type_ref_traits_t a9; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7, a8, a9); + } +}; + +//! ��������pyclass ��ʼ������ +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + + self->obj = new CLASS_TYPE(); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + if (pyext_tool.parse_arg(a1.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + type_ref_traits_t a9; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); + return 0; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(); + static int args_num() { return 0;} + static int option_args_num() { return 0;} + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1); + static int args_num() { return 1-option_args_num();} + static int option_args_num() { return pyoption_traits_t::value_t>::is();} + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + if (pyext_tool.parse_arg(a1.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2); + static int args_num() { return 2-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2);; + } +}; + + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3); + static int args_num() { return 3-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4); + static int args_num() { return 4-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5); + static int args_num() { return 5-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); + static int args_num() { return 6-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); + static int args_num() { return 7-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); + static int args_num() { return 8-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8);; + } +}; + + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); + static int args_num() { return 9-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + type_ref_traits_t a9; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8, a9);; + } +}; + +//! const类型成员函数--------------------------------------------------------------------------------------------- + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)() const; + static int args_num() { return 0;} + static int option_args_num() { return 0;} + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1) const; + static int args_num() { return 1-option_args_num();} + static int option_args_num() { return pyoption_traits_t::value_t>::is();} + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + if (pyext_tool.parse_arg(a1.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2) const; + static int args_num() { return 2-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2);; + } +}; + + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3) const; + static int args_num() { return 3-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4) const; + static int args_num() { return 4-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5) const; + static int args_num() { return 5-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) const; + static int args_num() { return 6-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) const; + static int args_num() { return 7-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8) const; + static int args_num() { return 8-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8);; + } +}; + + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9) const; + static int args_num() { return 9-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + type_ref_traits_t a9; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8, a9);; + } +}; + + +#endif diff --git a/python2.7/ffpython.h b/python2.7/ffpython.h new file mode 100644 index 0000000..1b95049 --- /dev/null +++ b/python2.7/ffpython.h @@ -0,0 +1,3931 @@ +#ifndef __FFPYTHON_H_ +#define __FFPYTHON_H_ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +#ifdef _WIN32 +#define SAFE_SPRINTF _snprintf_s +#else +#define SAFE_SPRINTF snprintf +#endif + + +//! 获取python异常信息 +struct pyops_t +{ + static int traceback(string& ret_) + { + PyObject* err = PyErr_Occurred(); + + if (err != NULL) { + PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL; + PyObject *pyth_module = NULL, *pyth_func = NULL; + + PyErr_Fetch(&ptype, &pvalue, &ptraceback); + if (pvalue) + { + if (true == PyList_Check(pvalue)) + { + int n = PyList_Size(pvalue); + for (int i = 0; i < n; ++i) + { + PyObject *pystr = PyObject_Str(PyList_GetItem(pvalue, i)); + ret_ += PyString_AsString(pystr); + ret_ += "\n"; + Py_DECREF(pystr); + } + } + if (true == PyTuple_Check(pvalue)) + { + int n = PyTuple_Size(pvalue); + for (int i = 0; i < n; ++i) + { + PyObject* tmp_str = PyTuple_GetItem(pvalue, i); + if (true == PyTuple_Check(tmp_str)) + { + int m = PyTuple_Size(tmp_str); + for (int j = 0; j < m; ++j) + { + PyObject *pystr = PyObject_Str(PyTuple_GetItem(tmp_str, j)); + ret_ += PyString_AsString(pystr); + ret_ += ","; + Py_DECREF(pystr); + } + } + else + { + PyObject *pystr = PyObject_Str(tmp_str); + ret_ += PyString_AsString(pystr); + Py_DECREF(pystr); + } + ret_ += "\n"; + } + } + else + { + PyObject *pystr = PyObject_Str(pvalue); + if (pystr) + { + ret_ += PyString_AsString(pystr); + ret_ += "\n"; + Py_DECREF(pystr); + } + } + } + + /* See if we can get a full traceback */ + PyObject *module_name = PyString_FromString("traceback"); + pyth_module = PyImport_Import(module_name); + Py_DECREF(module_name); + + if (pyth_module && ptype && pvalue && ptraceback) + { + pyth_func = PyObject_GetAttrString(pyth_module, "format_exception"); + if (pyth_func && PyCallable_Check(pyth_func)) { + PyObject *pyth_val = PyObject_CallFunctionObjArgs(pyth_func, ptype, pvalue, ptraceback, NULL); + if (pyth_val && true == PyList_Check(pyth_val)) + { + int n = PyList_Size(pyth_val); + for (int i = 0; i < n; ++i) + { + PyObject* tmp_str = PyList_GetItem(pyth_val, i); + PyObject *pystr = PyObject_Str(tmp_str); + if (pystr) + { + ret_ += PyString_AsString(pystr); + + Py_DECREF(pystr); + } + ret_ += "\n"; + } + } + Py_XDECREF(pyth_val); + } + } + Py_XDECREF(pyth_func); + Py_XDECREF(pyth_module); + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + PyErr_Clear(); + return 0; + } + + return -1; + } +}; +struct cpp_void_t{}; + +//! 用于抽取类型、类型对应的引用 +template +struct type_ref_traits_t; + +//! 用于python 可选参数 +template +struct pyoption_t +{ + typedef typename type_ref_traits_t::value_t value_t; + pyoption_t():m_set_flag(false){} + bool is_set() const { return m_set_flag;} + void set() { m_set_flag = true;} + value_t& value() { return m_value;} + const value_t& value() const{ return m_value;} + + const value_t& value(const value_t& default_) + { + if (is_set()) + return m_value; + else + return default_; + } + bool m_set_flag; + value_t m_value; +}; +//! 用于判断是否是可选参数 +template +struct pyoption_traits_t; + +//! pytype_traits_t 封装 PyLong_FromLong 相关的操作,用于为调用python生成参数 +template +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const char* const val_) + { + return PyString_FromString(val_); + } + /* + static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) + { + if (true == PyString_Check(pvalue_)) + { + m_ret = PyString_AsString(pvalue_); + return 0; + } + return -1; + } + */ + static const char* get_typename() { return "string";} +}; + +//! 用于调用python函数,生成tuple类型的python函数参数的工具类 +struct pycall_arg_t +{ + pycall_arg_t(int arg_num): + arg_index(0), + pargs_tuple(PyTuple_New(arg_num)) + {} + ~pycall_arg_t() + { + release(); + } + PyObject * get_args() const + { + return pargs_tuple; + } + template + pycall_arg_t& add(const T& val_) + { + if (arg_index < PyTuple_Size(pargs_tuple)) + { + PyObject* tmp_arg = pytype_traits_t::pyobj_from_cppobj(val_); + PyTuple_SetItem(pargs_tuple, arg_index, tmp_arg); + ++arg_index; + } + return *this; + } + void release() + { + if (pargs_tuple) + { + Py_DECREF(pargs_tuple); + pargs_tuple = NULL; + } + } + int arg_index; + PyObject * pargs_tuple; +}; + +//! 用于调用python函数,获取返回值的工具类 +class pytype_tool_t +{ +public: + virtual ~pytype_tool_t(){}; + virtual int parse_value(PyObject *pvalue_) = 0; + virtual const char* return_type() {return "";} + virtual bool need_release() { return true; } +}; + +//! 用于调用python函数,获取返回值的工具泛型类 +template +class pytype_tool_impl_t; +//! 封装调用python函数的C API +struct pycall_t +{ + static int call_func(PyObject *pModule, const string& mod_name_, const string& func_name_, + pycall_arg_t& pyarg_, pytype_tool_t& pyret_, string& err_) + { + PyObject *pFunc = PyObject_GetAttrString(pModule, func_name_.c_str()); + if (pFunc && PyCallable_Check(pFunc)) { + PyObject *pArgs = pyarg_.get_args(); + PyObject *pValue = PyObject_CallObject(pFunc, pArgs); + pyarg_.release();//! 等价于Py_DECREF(pArgs); + + if (pValue != NULL) { + if (pyret_.parse_value(pValue)) + { + err_ += "value returned is not "; + err_ += pyret_.return_type(); + err_ += string(" ") + func_name_ + " in " + mod_name_; + } + if (pyret_.need_release()){ + Py_DECREF(pValue); + } + } + } + else + { + err_ += "Cannot find function "; + err_ += func_name_ + " in " + mod_name_ + ","; + } + + Py_XDECREF(pFunc); + if (PyErr_Occurred()) + { + pyops_t::traceback(err_); + return 0; + } + return 0; + } + static int call_func_obj(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_t& pyret_, string& err_) + { + if (pFunc && PyCallable_Check(pFunc)) { + PyObject *pArgs = pyarg_.get_args(); + PyObject *pValue = PyObject_CallObject(pFunc, pArgs); + pyarg_.release();//! 等价于Py_DECREF(pArgs); + + if (pValue != NULL) { + if (pyret_.parse_value(pValue)) + { + err_ += "value returned is not "; + err_ += pyret_.return_type(); + } + if (pyret_.need_release()){ + Py_DECREF(pValue); + } + } + } + else + { + err_ += "invalid function"; + } + + if (PyErr_Occurred()) + { + pyops_t::traceback(err_); + return 0; + } + return 0; + } + template + static const T& call(const string& mod_name_, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); + template + static const T& call_obj_method(PyObject *pObj, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); + template + static const T& call_lambda(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); +}; +//! 用于扩展python的工具类,用来解析参数 +struct pyext_tool_t; + + +template +struct pyext_return_tool_t; + +//! 用于扩展python,生成pyobject类型的返回值给python +template +struct pyext_func_traits_t; + +//! 用于扩展python,traits出注册给python的函数接口 +#ifndef PYCTOR +#define PYCTOR int (*) +#endif +//! 表示void类型,由于void类型不能return,用void_ignore_t适配 +template +struct void_ignore_t; + +template +struct void_ignore_t +{ + typedef T value_t; +}; + +template<> +struct void_ignore_t +{ + typedef cpp_void_t value_t; +}; + +#define RET_V typename void_ignore_t::value_t + +//! 记录各个基类和子类的相互关系 +struct cpp_to_pyclass_reg_info_t +{ + struct inherit_info_t + { + inherit_info_t():pytype_def(NULL){} + PyTypeObject* pytype_def; + string inherit_name; + set all_child; + }; + typedef map inherit_info_map_t; + static inherit_info_map_t& get_all_info() + { + static inherit_info_map_t inherit_info; + return inherit_info; + } + + static void add(const string& child_, const string& base_, PyTypeObject* def_) + { + inherit_info_t tmp; + tmp.inherit_name = base_; + tmp.pytype_def = def_; + get_all_info()[child_] = tmp; + get_all_info()[base_].all_child.insert(def_); + } + static bool is_instance(PyObject* pysrc, const string& class_) + { + inherit_info_map_t& inherit_info = get_all_info(); + inherit_info_t& tmp = inherit_info[class_]; + if (tmp.pytype_def && PyObject_TypeCheck(pysrc, tmp.pytype_def)) + { + return true; + } + for (set::iterator it = tmp.all_child.begin(); it != tmp.all_child.end(); ++it) + { + if (*it && PyObject_TypeCheck(pysrc, *it)) + { + return true; + } + } + + return false; + } + +}; + + +//! 记录C++ class 对应到python中的名称、参数信息等,全局 +struct static_pytype_info_t +{ + string class_name; + string mod_name; + int total_args_num; + PyTypeObject* pytype_def; +}; + +//! 工具类,用于生成分配python class的接口,包括分配、释放 +template +struct pyclass_base_info_t +{ + struct obj_data_t + { + obj_data_t():obj(NULL){} + + PyObject_HEAD; + T* obj; + bool forbid_release; + void disable_auto_release(){ forbid_release = true; } + void release() + { + if (obj) + { + delete obj; + obj = NULL; + } + } + }; + + static void free_obj(obj_data_t* self) + { + if (false == self->forbid_release && self->obj) + { + self->release(); + } + self->ob_type->tp_free((PyObject*)self); + } + + static PyObject *alloc_obj(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + obj_data_t *self = (obj_data_t *)type->tp_alloc(type, 0); + return (PyObject *)self; + } + static PyObject *release(PyTypeObject *type, PyObject *args) + { + obj_data_t *self = (obj_data_t *)type; + self->release(); + return Py_BuildValue("i", 1); + } + static static_pytype_info_t pytype_info; +}; +template +static_pytype_info_t pyclass_base_info_t::pytype_info; + +//! 方便生成pyclass 初始化函数 +template +struct pyclass_ctor_tool_t; + +//! used to gen method of py class +template +struct pyclass_method_gen_t; + +//! 防止出现指针为NULL调用出错 +#define NULL_PTR_GUARD(X) if (NULL == X) {PyErr_SetString(PyExc_TypeError, "obj data ptr NULL");return NULL;} + +//! 用于生成python 的getter和setter接口,适配于c++ class的成员变量 +template +struct pyclass_member_func_gen_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + typedef RET CLASS_TYPE::* property_ptr_t; + + static PyObject *getter_func(obj_data_t *self, void *closure) + { + property_ptr_t property_ptr; + ::memcpy((void*)&property_ptr, (const void*)&closure, sizeof(closure)); + NULL_PTR_GUARD(self->obj); + CLASS_TYPE* p = self->obj; + return pytype_traits_t::pyobj_from_cppobj(p->*property_ptr); + } + static int setter_func(obj_data_t *self, PyObject *value, void *closure) + { + property_ptr_t property_ptr; + ::memcpy((void*)&property_ptr, (const void*)&closure, sizeof(closure)); + CLASS_TYPE* p = self->obj; + + return pytype_traits_t::pyobj_to_cppobj(value, p->*property_ptr); + } +}; + +//! 用于C++ 注册class的工具类,会记录class对应的名称、成员方法、成员变量 +class pyclass_regigster_tool_t +{ +public: + struct method_info_t + { + PyCFunction func; + string func_name; + string func_real_name; + string doc; + string doc_real; + int args_num; + int option_args_num; + long func_addr; + }; + struct property_info_t + { + void* ptr; + string property_name; + string doc; + getter getter_func; + setter setter_func; + }; + virtual ~pyclass_regigster_tool_t(){} + + typedef PyObject *(*pyobj_alloc_t)(PyTypeObject*, PyObject*, PyObject*); + + string class_name; + string class_real_name; + string class_name_with_mod; + string class_reel_name_with_mod; + string inherit_name; + int type_size; + string doc; + int args_num; + int option_args_num; + destructor dector; + initproc init; + pyobj_alloc_t ctor; + + //! member functions + PyCFunction delete_func; + vector methods_info; + //! property + vector propertys_info; + //! for init module + PyTypeObject pytype_def; + //! method + vector pymethod_def; + //! property + vector pyproperty_def; + + //! 静态类型需要全局记录该类型被注册成神马python 类型 + static_pytype_info_t* static_pytype_info; + + template + pyclass_regigster_tool_t& reg(FUNC f_, const string& func_name_, string doc_ = "") + { + method_info_t tmp; + tmp.func_name = func_name_; + tmp.func_real_name = func_name_ + "_internal_"; + tmp.doc = doc_; + tmp.doc_real = "internal use"; + tmp.func = (PyCFunction)pyclass_method_gen_t::pymethod; + tmp.args_num = pyclass_method_gen_t::args_num(); + tmp.option_args_num = pyclass_method_gen_t::option_args_num(); + + ::memcpy((void*)&tmp.func_addr, (const void*)&f_, sizeof(void*)); + methods_info.push_back(tmp); + return *this; + } + template + pyclass_regigster_tool_t& reg_property(RET CLASS_TYPE::* member_, const string& member_name_, string doc_ = "") + { + property_info_t tmp; + ::memcpy((void*)&tmp.ptr, (const void*)&member_, sizeof(member_)); + tmp.property_name = member_name_; + tmp.doc = doc_; + tmp.getter_func = (getter)pyclass_member_func_gen_t::getter_func; + tmp.setter_func = (setter)pyclass_member_func_gen_t::setter_func; + propertys_info.push_back(tmp); + return *this; + } +}; + + +class ffpython_t +{ +public: + typedef std::string (*ModInitFunc)(ffpython_t&); + struct reg_info_t + { + reg_info_t():args_num(0),option_args_num(0),func_addr(0){} + int args_num; + int option_args_num; + long func_addr; + PyCFunction func; + string func_name; + string func_impl_name; + string doc; + string doc_impl; + }; + +public: + ffpython_t(ModInitFunc func = NULL) + { + if (!Py_IsInitialized()) + Py_Initialize(); + if (func) { + std::string modName = func(*this); + init(modName); + } + } + ~ffpython_t() + { + clear_cache_pyobject(); + } + + static int init_py() + { + Py_Initialize(); + return 0; + } + static int final_py() + { + Py_Finalize(); + return 0; + } + + static int add_path(const string& path_) + { + char buff[1024]; + SAFE_SPRINTF(buff, sizeof(buff), "import sys\nif '%s' not in sys.path:\n\tsys.path.append('%s')\n", path_.c_str(), path_.c_str()); + PyRun_SimpleString(buff); + return 0; + } + + static int run_string(const string& py_) + { + PyRun_SimpleString(py_.c_str()); + return 0; + } + + static int reload(const string& py_name_) + { + PyObject *pName = NULL, *pModule = NULL; + string err_msg; + + pName = PyString_FromString(py_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return -1; + } + + PyObject *pNewMod = PyImport_ReloadModule(pModule); + Py_DECREF(pModule); + if (NULL == pNewMod) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return -1; + } + Py_DECREF(pNewMod); + return 0; + } + static int load(const string& py_name_) + { + PyObject *pName = NULL, *pModule = NULL; + string err_msg; + + pName = PyString_FromString(py_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return -1; + } + + Py_DECREF(pModule); + return 0; + } + + //! 注册static function, + template + ffpython_t& reg(T func_, const string& func_name_, string doc_ = "") + { + reg_info_t tmp; + tmp.args_num = pyext_func_traits_t::args_num(); + tmp.option_args_num = pyext_func_traits_t::option_args_num(); + tmp.func = (PyCFunction)pyext_func_traits_t::pyfunc; + tmp.func_name= func_name_; + tmp.func_impl_name = func_name_ + "_internal_"; + tmp.doc = doc_; + tmp.doc_impl = string("internal use, please call ") + func_name_; + tmp.func_addr= (long)func_; + + m_func_info.push_back(tmp); + return *this; + } + + //! 注册c++ class + template + pyclass_regigster_tool_t& reg_class(const string& class_name_, string doc_ = "", string inherit_name_ = "") + { + if (pyclass_base_info_t::pytype_info.class_name.empty() == false) + throw runtime_error("this type has been registed"); + + pyclass_base_info_t::pytype_info.class_name = class_name_; + //pyclass_base_info_t::pytype_info.mod_name = m_mod_name; + pyclass_base_info_t::pytype_info.total_args_num = pyext_func_traits_t::args_num() + + pyext_func_traits_t::option_args_num(); + + pyclass_regigster_tool_t tmp; + tmp.class_name = class_name_; + tmp.class_real_name = class_name_ + "_internal_"; + tmp.inherit_name = inherit_name_; + tmp.doc = doc_; + tmp.dector = (destructor)pyclass_base_info_t::free_obj; + tmp.init = (initproc)pyclass_ctor_tool_t::init_obj; + tmp.ctor = pyclass_base_info_t::alloc_obj; + tmp.type_size = sizeof(typename pyclass_base_info_t::obj_data_t); + tmp.args_num = pyext_func_traits_t::args_num(); + tmp.option_args_num = pyext_func_traits_t::option_args_num(); + tmp.static_pytype_info = &(pyclass_base_info_t::pytype_info); + //! 注册析构函数,python若不调用析构函数,当对象被gc时自动调用 + tmp.delete_func = (PyCFunction)pyclass_base_info_t::release; + m_all_pyclass.push_back(tmp); + + return m_all_pyclass.back(); + } + + + //! 调用python函数,最多支持9个参数 + template + RET_V call(const string& mod_name_, const string& func_) + { + pycall_arg_t args(0); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1) + { + pycall_arg_t args(1); + args.add(a1); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2) + { + pycall_arg_t args(2); + args.add(a1).add(a2); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3) + { + pycall_arg_t args(3); + args.add(a1).add(a2).add(a3); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) + { + pycall_arg_t args(4); + args.add(a1).add(a2).add(a3).add(a4); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5) + { + pycall_arg_t args(5); + args.add(a1).add(a2).add(a3).add(a4).add(a5); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5,const ARG6& a6) + { + pycall_arg_t args(6); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5,const ARG6& a6,const ARG7& a7) + { + pycall_arg_t args(7); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) + { + pycall_arg_t args(8); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) + { + pycall_arg_t args(9); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8).add(a9); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + //!call python class method begin****************************************************************** + template + RET_V obj_call(PyObject* pobj, const string& func_) + { + pycall_arg_t args(0); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1) + { + pycall_arg_t args(1); + args.add(a1); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2) + { + pycall_arg_t args(2); + args.add(a1).add(a2); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3) + { + pycall_arg_t args(3); + args.add(a1).add(a2).add(a3); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) + { + pycall_arg_t args(4); + args.add(a1).add(a2).add(a3).add(a4); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5) + { + pycall_arg_t args(5); + args.add(a1).add(a2).add(a3).add(a4).add(a5); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5,const ARG6& a6) + { + pycall_arg_t args(6); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5,const ARG6& a6,const ARG7& a7) + { + pycall_arg_t args(7); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) + { + pycall_arg_t args(8); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) + { + pycall_arg_t args(9); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8).add(a9); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + //!call python class method end****************************************************************** + + //!call python lambad function begin ############################################################ + template + RET_V call_lambda(PyObject* pobj) + { + pycall_arg_t args(0); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1) + { + pycall_arg_t args(1); + args.add(a1); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2) + { + pycall_arg_t args(2); + args.add(a1).add(a2); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3) + { + pycall_arg_t args(3); + args.add(a1).add(a2).add(a3); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) + { + pycall_arg_t args(4); + args.add(a1).add(a2).add(a3).add(a4); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5) + { + pycall_arg_t args(5); + args.add(a1).add(a2).add(a3).add(a4).add(a5); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5,const ARG6& a6) + { + pycall_arg_t args(6); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5,const ARG6& a6,const ARG7& a7) + { + pycall_arg_t args(7); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) + { + pycall_arg_t args(8); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) + { + pycall_arg_t args(9); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8).add(a9); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + //!call python lambad function ennd ############################################################ + template + RET_V get_global_var(const string& mod_name_, const string& var_name_) + { + PyObject *pName = NULL, *pModule = NULL; + string err_msg; + + pName = PyString_FromString(mod_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + } + + pytype_tool_impl_t pyret; + PyObject *pvalue = PyObject_GetAttrString(pModule, var_name_.c_str()); + Py_DECREF(pModule); + + if (!pvalue) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + } + + if (pyret.parse_value(pvalue)) + { + Py_XDECREF(pvalue); + throw runtime_error("type invalid"); + } + Py_XDECREF(pvalue); + return pyret.get_value(); + } + + template + int set_global_var(const string& mod_name_, const string& var_name_, const T& val_) + { + PyObject *pName = NULL, *pModule = NULL; + string err_msg; + + pName = PyString_FromString(mod_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + } + + PyObject* pval = pytype_traits_t::pyobj_from_cppobj(val_); + int ret = PyObject_SetAttrString(pModule, var_name_.c_str(), pval); + Py_DECREF(pModule); + + return ret != -1? 0: -1; + } + template + RET_V getattr(PyObject* pModule, const string& var_name_) + { + string err_msg; + if (NULL == pModule) + { + throw runtime_error("getattr object ptr null"); + } + + pytype_tool_impl_t pyret; + PyObject *pvalue = PyObject_GetAttrString(pModule, var_name_.c_str()); + + if (!pvalue) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + } + + if (pyret.parse_value(pvalue)) + { + Py_XDECREF(pvalue); + throw runtime_error("type invalid"); + } + Py_XDECREF(pvalue); + return pyret.get_value(); + } + void cache_pyobject(PyObject* pobj) + { + m_cache_pyobject.push_back(pobj); + } + void clear_cache_pyobject() + { + if (Py_IsInitialized()) + { + for (size_t i = 0; i < m_cache_pyobject.size(); ++i) + { + Py_XDECREF(m_cache_pyobject[i]); + } + m_cache_pyobject.clear(); + } + } +private: + //! 将需要注册的函数、类型注册到python虚拟机 + int init(const string& mod_name_, string doc_ = "") + { + m_mod_name = mod_name_; + m_mod_doc = doc_; + PyObject* m = init_method(); + init_pyclass(m); + return 0; + } + PyObject* init_method() + { + string mod_name_ = m_mod_name; + string doc_ = m_mod_doc; + + if (m_pymethod_defs.empty()) + { + m_pymethod_defs.reserve(m_func_info.size() + 1); + + for (size_t i = 0; i < m_func_info.size(); ++i) + { + PyMethodDef tmp = {m_func_info[i].func_impl_name.c_str(), m_func_info[i].func, + METH_VARARGS, m_func_info[i].doc_impl.c_str()}; + m_pymethod_defs.push_back(tmp); + } + PyMethodDef tmp = {NULL}; + m_pymethod_defs.push_back(tmp); + } + + PyObject* m = Py_InitModule3(m_mod_name.c_str(), &(m_pymethod_defs.front()), doc_.c_str()); + + for (size_t i = 0; i < m_func_info.size(); ++i) + { + string pystr_args; + string pystr_args_only_name; + for (int j = 0; j < m_func_info[i].args_num; ++j) + { + stringstream ss; + if (pystr_args.empty()) + { + ss << "a" << (j+1); + pystr_args += ss.str(); + } + else + { + ss << ", a" << (j+1); + pystr_args += ss.str(); + } + } + pystr_args_only_name = pystr_args; + for (int j = 0; j < m_func_info[i].option_args_num; ++j) + { + stringstream ss; + if (pystr_args.empty()) + { + ss << "a" << (m_func_info[i].args_num + j+1); + string tmp = ss.str(); + pystr_args_only_name += tmp; + pystr_args += tmp + " = None"; + } + else + { + ss << ", a" << (m_func_info[i].args_num + j+1); + string tmp = ss.str(); + pystr_args_only_name += tmp; + pystr_args += tmp + " = None"; + } + } + if (!pystr_args_only_name.empty()) + pystr_args_only_name += ","; + + char buff[1024]; + SAFE_SPRINTF(buff, sizeof(buff), + "_tmp_ff_ = None\nif '%s' in globals():\n\t_tmp_ff_ = globals()['%s']\n" + "def %s(%s):\n" + "\t'''%s'''\n" + "\treturn %s.%s(%ld,(%s))\n" + "import %s\n" + "%s.%s = %s\n" + "%s = None\n" + "if _tmp_ff_:\n\tglobals()['%s'] = _tmp_ff_\n_tmp_ff_ = None\n", + m_func_info[i].func_name.c_str(), m_func_info[i].func_name.c_str(), + m_func_info[i].func_name.c_str(), pystr_args.c_str(), + m_func_info[i].doc.c_str(), + m_mod_name.c_str(), m_func_info[i].func_impl_name.c_str(), m_func_info[i].func_addr, pystr_args_only_name.c_str(), + m_mod_name.c_str(), + m_mod_name.c_str(), m_func_info[i].func_name.c_str(), m_func_info[i].func_name.c_str(), + m_func_info[i].func_name.c_str(), + m_func_info[i].func_name.c_str() + ); + + //printf(buff); + PyRun_SimpleString(buff); + } + + return m; + } + int init_pyclass(PyObject* m) + { + for (size_t i = 0; i < m_all_pyclass.size(); ++i) + { + m_all_pyclass[i].static_pytype_info->mod_name = m_mod_name; + if (false == m_all_pyclass[i].inherit_name.empty())//! ���ڻ��� + { + pyclass_regigster_tool_t* inherit_class = get_pyclass_info_by_name(m_all_pyclass[i].inherit_name); + assert(inherit_class && "base class must be registed"); + for (size_t n = 0; n < inherit_class->methods_info.size(); ++n) + { + const string& method_name = inherit_class->methods_info[n].func_name; + if (false == is_method_exist(m_all_pyclass[i].methods_info, method_name)) + { + m_all_pyclass[i].methods_info.push_back(inherit_class->methods_info[n]); + } + } + for (size_t n = 0; n < inherit_class->propertys_info.size(); ++n) + { + const string& property_name = inherit_class->propertys_info[n].property_name; + if (false == is_property_exist(m_all_pyclass[i].propertys_info, property_name)) + { + m_all_pyclass[i].propertys_info.push_back(inherit_class->propertys_info[n]); + } + } + } + //! init class property + for (size_t j = 0; j < m_all_pyclass[i].propertys_info.size(); ++j) + { + PyGetSetDef tmp = {(char*)m_all_pyclass[i].propertys_info[j].property_name.c_str(), + m_all_pyclass[i].propertys_info[j].getter_func, + m_all_pyclass[i].propertys_info[j].setter_func, + (char*)m_all_pyclass[i].propertys_info[j].doc.c_str(), + m_all_pyclass[i].propertys_info[j].ptr + }; + m_all_pyclass[i].pyproperty_def.push_back(tmp); + } + PyGetSetDef tmp_property_def = {NULL}; + m_all_pyclass[i].pyproperty_def.push_back(tmp_property_def); + //! init class method + for (size_t j = 0; j < m_all_pyclass[i].methods_info.size(); ++j) + { + PyMethodDef tmp = {m_all_pyclass[i].methods_info[j].func_real_name.c_str(), + m_all_pyclass[i].methods_info[j].func, + METH_VARARGS, + m_all_pyclass[i].methods_info[j].doc.c_str() + }; + m_all_pyclass[i].pymethod_def.push_back(tmp); + + } + PyMethodDef tmp_del = {"delete", + m_all_pyclass[i].delete_func, + METH_VARARGS, + "delete obj" + }; + m_all_pyclass[i].pymethod_def.push_back(tmp_del); + PyMethodDef tmp_method_def = {NULL}; + m_all_pyclass[i].pymethod_def.push_back(tmp_method_def); + + m_all_pyclass[i].class_name_with_mod = m_mod_name + "." + m_all_pyclass[i].class_name; + m_all_pyclass[i].class_reel_name_with_mod = m_mod_name + "." + m_all_pyclass[i].class_real_name; + + PyTypeObject tmp_pytype_def = + { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + m_all_pyclass[i].class_reel_name_with_mod.c_str(), /*tp_name*/ + m_all_pyclass[i].type_size, /*tp_size*/ + 0, /*tp_itemsize*/ + (destructor)m_all_pyclass[i].dector, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + m_all_pyclass[i].doc.c_str(), /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + &(m_all_pyclass[i].pymethod_def.front()),//Noddy_methods, /* tp_methods */ + 0,//Noddy_members, /* tp_members */ + &(m_all_pyclass[i].pyproperty_def.front()),//Noddy_getseters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)m_all_pyclass[i].init, /* tp_init */ + 0, /* tp_alloc */ + m_all_pyclass[i].ctor, /* tp_new */ + }; + m_all_pyclass[i].pytype_def = tmp_pytype_def; + m_all_pyclass[i].static_pytype_info->pytype_def = &m_all_pyclass[i].pytype_def; + cpp_to_pyclass_reg_info_t::add(m_all_pyclass[i].class_name, m_all_pyclass[i].inherit_name, &m_all_pyclass[i].pytype_def); + + if (PyType_Ready((PyTypeObject *)(&(m_all_pyclass[i].pytype_def))) < 0) + return -1; + PyObject* tmpP = (PyObject*)(&(m_all_pyclass[i].pytype_def)); + Py_INCREF(tmpP); + PyModule_AddObject(m, m_all_pyclass[i].class_real_name.c_str(), (PyObject *)&m_all_pyclass[i].pytype_def); + + stringstream str_def_args; + stringstream str_init_args; + for (int a = 0; a < m_all_pyclass[i].args_num; ++a) + { + str_def_args << "a"<<(a+1)<<","; + str_init_args << "a"<<(a+1)<<","; + } + for (int b = 0; b < m_all_pyclass[b].option_args_num; ++b) + { + str_def_args << "a"<<(m_all_pyclass[i].args_num+ b+1)<<" = None,"; + str_init_args << "a"<<(m_all_pyclass[i].args_num+ b+1)<<","; + } + + char buff[1024]; + SAFE_SPRINTF(buff, sizeof(buff), + "_tmp_ff_ = None\nif '%s' in globals():\n\t_tmp_ff_ = globals()['%s']\n" + "import %s\n" + "class %s(object):\n" + "\t'''%s'''\n" + "\tdef __init__(self, %s assign_obj_ = 0):\n"//! ����init���� + "\t\t'''%s'''\n" + "\t\tif True == isinstance(assign_obj_, %s):\n" + "\t\t\tself.obj = assign_obj_\n" + "\t\t\treturn\n" + "\t\tself.obj = %s(0,(%s))\n", + m_all_pyclass[i].class_name.c_str(), m_all_pyclass[i].class_name.c_str(), + m_mod_name.c_str(), + m_all_pyclass[i].class_name.c_str(), + m_all_pyclass[i].doc.c_str(), + str_def_args.str().c_str(), + "init class", + m_all_pyclass[i].class_reel_name_with_mod.c_str(), + m_all_pyclass[i].class_reel_name_with_mod.c_str(), str_init_args.str().c_str() + ); + + string gen_class_str = buff; + SAFE_SPRINTF(buff, sizeof(buff), + "\tdef delete(self):\n"//! ����init���� + "\t\t'''delete obj'''\n" + "\t\tself.obj.delete()\n"); + gen_class_str += buff; + //! 增加析构函数 + //! 增加属性 + for (size_t c = 0; c < m_all_pyclass[i].propertys_info.size(); ++c) + { + SAFE_SPRINTF(buff, sizeof(buff), + "\tdef get_%s(self):\n" + "\t\treturn self.obj.%s\n" + "\tdef set_%s(self, v):\n" + "\t\tself.obj.%s = v\n" + "\t@property\n" + "\tdef %s(self):\n" + "\t\treturn self.obj.%s\n" + "\t@%s.setter\n" + "\tdef %s(self, v):\n" + "\t\tself.obj.%s = v\n", + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str() + ); + gen_class_str += buff; + } + + for (size_t m = 0; m < m_all_pyclass[i].methods_info.size(); ++m) + { + string pystr_args; + string pystr_args_only_name; + for (int j = 0; j < m_all_pyclass[i].methods_info[m].args_num; ++j) + { + stringstream ss; + if (pystr_args.empty()) + { + ss << "a" << (j+1); + pystr_args += ss.str(); + } + else + { + ss << ", a" << (j+1); + pystr_args += ss.str(); + } + } + pystr_args_only_name = pystr_args; + for (int j = 0; j < m_all_pyclass[i].methods_info[m].option_args_num; ++j) + { + stringstream ss; + if (pystr_args.empty()) + { + ss << "a" << (m_all_pyclass[i].methods_info[m].args_num + j+1); + string tmp = ss.str(); + pystr_args_only_name += tmp; + pystr_args += tmp + " = None"; + } + else + { + ss << ", a" << (m_all_pyclass[i].methods_info[m].args_num + j+1); + string tmp = ss.str(); + pystr_args_only_name += tmp; + pystr_args += tmp + " = None"; + } + } + if (!pystr_args_only_name.empty()) + pystr_args_only_name += ","; + + SAFE_SPRINTF(buff, sizeof(buff), + "\tdef %s(self,%s):\n" + "\t\t'''%s'''\n" + "\t\treturn self.obj.%s(%ld,(%s))\n" + ,m_all_pyclass[i].methods_info[m].func_name.c_str(), pystr_args.c_str(), + m_all_pyclass[i].methods_info[m].doc.c_str(), + m_all_pyclass[i].methods_info[m].func_real_name.c_str(), m_all_pyclass[i].methods_info[m].func_addr, pystr_args_only_name.c_str() + ); + gen_class_str += buff; + } + SAFE_SPRINTF(buff, sizeof(buff), + "%s.%s = %s\n" + "%s = None\n" + "if _tmp_ff_:\n\tglobals()['%s'] = _tmp_ff_\n_tmp_ff_ = None\n", + m_mod_name.c_str(), m_all_pyclass[i].class_name.c_str(), m_all_pyclass[i].class_name.c_str(), + m_all_pyclass[i].class_name.c_str(), + m_all_pyclass[i].class_name.c_str() + ); + gen_class_str += buff; + //printf(gen_class_str.c_str()); + PyRun_SimpleString(gen_class_str.c_str()); + } + return 0; + } + + + + + bool is_method_exist(const vector& src_, const string& new_) + { + for (size_t i = 0; i < src_.size(); ++i) + { + if (new_ == src_[i].func_name) + { + return true; + } + } + return false; + } + bool is_property_exist(const vector& src_, const string& new_) + { + for (size_t i = 0; i < src_.size(); ++i) + { + if (new_ == src_[i].property_name) + { + return true; + } + } + return false; + } + pyclass_regigster_tool_t* get_pyclass_info_by_name(const string& name_) + { + for (size_t i = 0; i < m_all_pyclass.size(); ++i) + { + if (m_all_pyclass[i].class_name == name_) + { + return &(m_all_pyclass[i]); + } + } + return NULL; + } + + + + +private: + string m_mod_name; + string m_mod_doc; + vector m_pymethod_defs; + vector m_func_info; + + //! reg class + vector m_all_pyclass; + //! cache some pyobject for optimize + vector m_cache_pyobject; +}; + + +template +struct type_ref_traits_t +{ + typedef T value_t; + typedef T& ref_t; + value_t value; +}; +template +struct type_ref_traits_t +{ + typedef T value_t; + typedef T& ref_t; + value_t value; +}; +template +struct type_ref_traits_t +{ + typedef T value_t; + typedef T& ref_t; + value_t value; +}; +//! 用于判断是否是可选参数 +template +struct pyoption_traits_t +{ + static int is() { return 0;} +}; +template +struct pyoption_traits_t > +{ + static int is() { return 1;} +}; + + +template<>//typename T> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const long& val_) + { + return PyLong_FromLong(long(val_)); + } + static int pyobj_to_cppobj(PyObject *pvalue_, long& m_ret) + { + if (true == PyLong_Check(pvalue_)) + { + m_ret = (long)PyLong_AsLong(pvalue_); + return 0; + } + else if (true == PyInt_Check(pvalue_)) + { + m_ret = (long)PyInt_AsLong(pvalue_); + return 0; + } + return -1; + } + static const char* get_typename() { return "long";} +}; + +#define IMPL_INT_CODE(X) \ +template<> \ +struct pytype_traits_t \ +{ \ + static PyObject* pyobj_from_cppobj(const X& val_) \ + { \ + return PyInt_FromLong(long(val_)); \ + } \ + static int pyobj_to_cppobj(PyObject *pvalue_, X& m_ret) \ + { \ + if (true == PyLong_Check(pvalue_)) \ + { \ + m_ret = (X)PyLong_AsLong(pvalue_); \ + return 0; \ + } \ + else if (true == PyInt_Check(pvalue_)) \ + { \ + m_ret = (X)PyInt_AsLong(pvalue_); \ + return 0; \ + } \ + return -1; \ + } \ + static const char* get_typename() { return #X;} \ +}; + +IMPL_INT_CODE(int) +IMPL_INT_CODE(unsigned int) +IMPL_INT_CODE(short) +IMPL_INT_CODE(unsigned short) +IMPL_INT_CODE(char) +IMPL_INT_CODE(unsigned char) + +#ifdef _WIN32 +IMPL_INT_CODE(unsigned long) +#else +#ifndef __x86_64__ +IMPL_INT_CODE(int64_t) +#endif +IMPL_INT_CODE(uint64_t) +#endif + +template +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const T* val_) + { + const string& mod_name = pyclass_base_info_t::pytype_info.mod_name; + const string& class_name = pyclass_base_info_t::pytype_info.class_name; + PyObject *pName = NULL, *pModule = NULL, *pValue = NULL; + + if (class_name.empty()) + return pytype_traits_t::pyobj_from_cppobj(long(val_)); + + pName = PyString_FromString(mod_name.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + if (PyErr_Occurred()) + PyErr_Print(); + fprintf(stderr, "Failed to load \"%s\"\n", mod_name.c_str()); + assert(NULL && "this can not be happened"); + return NULL; + } + PyObject *pyclass = PyObject_GetAttrString(pModule, class_name.c_str()); + if (pyclass && PyCallable_Check(pyclass)) { + PyObject *pArgs = PyTuple_New(pyclass_base_info_t::pytype_info.total_args_num+1); + for (int i = 0; i< pyclass_base_info_t::pytype_info.total_args_num; ++i) + { + PyTuple_SetItem(pArgs, i, pytype_traits_t::pyobj_from_cppobj(0)); + } + + PyObject *palloc = pyclass_base_info_t::alloc_obj(pyclass_base_info_t::pytype_info.pytype_def, NULL, NULL); + typename pyclass_base_info_t::obj_data_t* pdest_obj = (typename pyclass_base_info_t::obj_data_t*)palloc; + //pdest_obj->obj = val_; + ::memcpy((void*)&pdest_obj->obj, (const void*)&val_, sizeof(pdest_obj->obj)); + pdest_obj->disable_auto_release(); + PyTuple_SetItem(pArgs, pyclass_base_info_t::pytype_info.total_args_num, palloc); + pValue = PyObject_CallObject(pyclass, pArgs); + Py_XDECREF(pArgs); + } + + Py_XDECREF(pyclass); + Py_DECREF(pModule); + return pValue; + } + + static int pyobj_to_cppobj(PyObject *pvalue_, T*& m_ret) + { + PyObject *pysrc = PyObject_GetAttrString(pvalue_, "obj"); + //!PyObject_TypeCheck(pysrc, pyclass_base_info_t::pytype_info.pytype_def)) { + if (NULL == pysrc || false == cpp_to_pyclass_reg_info_t::is_instance(pysrc, pyclass_base_info_t::pytype_info.class_name)) + { + Py_XDECREF(pysrc); + return -1; + } + typename pyclass_base_info_t::obj_data_t* pdest_obj = (typename pyclass_base_info_t::obj_data_t*)pysrc; + + m_ret = pdest_obj->obj; + Py_XDECREF(pysrc); + return 0; + } + + static const char* get_typename() { return pyclass_base_info_t::pytype_info.class_name.c_str();} +}; + +template +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(T* val_) + { + return pytype_traits_t::pyobj_from_cppobj(val_); + } + static int pyobj_to_cppobj(PyObject *pvalue_,T*& m_ret) + { + return pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret); + } + static const char* get_typename() { return pyclass_base_info_t::pytype_info.class_name.c_str();} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(PyObject* val_) + { + return val_; + } + static int pyobj_to_cppobj(PyObject *pvalue_, PyObject*& m_ret) + { + m_ret = pvalue_; + return 0; + } + static const char* get_typename() { return "PyObject";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const char* const val_) + { + return PyString_FromString(val_); + } + /* + static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) + { + if (true == PyString_Check(pvalue_)) + { + m_ret = PyString_AsString(pvalue_); + return 0; + } + return -1; + } + */ + static const char* get_typename() { return "string";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const char*& val_) + { + return PyString_FromString(val_); + } + /* + static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) + { + if (true == PyString_Check(pvalue_)) + { + m_ret = PyString_AsString(pvalue_); + return 0; + } + return -1; + } + */ + static const char* get_typename() { return "string";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(bool val_) + { + if (val_) + { + return Py_BuildValue("i", 1); + } + return Py_BuildValue("i", 0); + } + static int pyobj_to_cppobj(PyObject *pvalue_, bool& m_ret) + { + if (Py_False == pvalue_|| Py_None == pvalue_) + { + m_ret = false; + } + else + { + m_ret = true; + } + return 0; + } + static const char* get_typename() { return "bool";} +}; + +template +struct pytype_traits_t > +{ + static int pyobj_to_cppobj(PyObject *pvalue_, pyoption_t& m_ret) + { + if (Py_None == pvalue_) + { + return 0; + } + else if (0 == pytype_traits_t::value_t>::pyobj_to_cppobj(pvalue_, m_ret.value())) + { + m_ret.set(); + return 0; + } + return -1; + } + static const char* get_typename() { return "pyoption_t";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const string& val_) + { + return PyString_FromStringAndSize(val_.c_str(), val_.size()); + } + static int pyobj_to_cppobj(PyObject *pvalue_, string& m_ret) + { + if (true == PyString_Check(pvalue_)) + { + char* pDest = NULL; + Py_ssize_t nLen = 0; + PyString_AsStringAndSize(pvalue_, &pDest, &nLen); + + m_ret.assign(pDest, nLen); + return 0; + } + else if (true == PyUnicode_Check(pvalue_)) + { + char* pDest = NULL; + Py_ssize_t nLen = 0; + PyString_AsStringAndSize(pvalue_, &pDest, &nLen); + m_ret.assign(pDest, nLen); + return 0; + /* +#ifdef _WIN32 + PyObject* retStr = PyUnicode_AsEncodedString(pvalue_, "gbk", ""); +#else + PyObject* retStr = PyUnicode_AsUTF8String(pvalue_); +#endif + if (retStr) + { + m_ret = PyString_AsString(retStr); + Py_XDECREF(retStr); + return 0; + } + */ + } + return -1; + } + static const char* get_typename() { return "string";} +}; + +#ifdef _WIN32 +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const wstring& wstr) + { + return PyUnicode_FromWideChar(wstr.c_str(), wstr.length()); + } + static int pyobj_to_cppobj(PyObject *pvalue_, wstring& wstr_ret) + { + if (true == PyString_Check(pvalue_)) + { + PyObject* retStr = PyUnicode_FromObject(pvalue_); + if (retStr) + { + int n = PyUnicode_GetSize(retStr); + wstr_ret.resize(n); + n = PyUnicode_AsWideChar((PyUnicodeObject*)retStr, &(wstr_ret[0]), n); + Py_XDECREF(retStr); + return 0; + } + return 0; + } + else if (true == PyUnicode_Check(pvalue_)) + { + int n = PyUnicode_GetSize(pvalue_); + wstr_ret.resize(n); + n = PyUnicode_AsWideChar((PyUnicodeObject*)pvalue_, &(wstr_ret[0]), n); + return 0; + } + return -1; + } + static const char* get_typename() { return "wstring";} +}; +#endif + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(float val_) + { + return PyFloat_FromDouble(double(val_)); + } + static int pyobj_to_cppobj(PyObject *pvalue_, float& m_ret) + { + if (true == PyFloat_Check(pvalue_)) + { + m_ret = (float)PyFloat_AsDouble(pvalue_); + return 0; + } + return -1; + } + static const char* get_typename() { return "float";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(double val_) + { + return PyFloat_FromDouble(val_); + } + static int pyobj_to_cppobj(PyObject *pvalue_, double& m_ret) + { + if (true == PyFloat_Check(pvalue_)) + { + m_ret = PyFloat_AsDouble(pvalue_); + return 0; + } + return -1; + } + static const char* get_typename() { return "double";} +}; + +template +struct pytype_traits_t > +{ + static PyObject* pyobj_from_cppobj(const vector& val_) + { + PyObject* ret = PyList_New(val_.size()); + for (size_t i = 0; i < val_.size(); ++i) + { + PyList_SetItem(ret, i, pytype_traits_t::pyobj_from_cppobj(val_[i])); + } + return ret; + } + static int pyobj_to_cppobj(PyObject *pvalue_, vector& m_ret) + { + m_ret.clear(); + if (true == PyTuple_Check(pvalue_)) + { + int n = PyTuple_Size(pvalue_); + for (int i = 0; i < n; ++i) + { + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyTuple_GetItem(pvalue_, i))) + { + return -1; + } + m_ret.push_back(ret_tool.get_value()); + } + return 0; + } + else if (true == PyList_Check(pvalue_)) + { + int n = PyList_Size(pvalue_); + for (int i = 0; i < n; ++i) + { + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyList_GetItem(pvalue_, i))) + { + return -1; + } + m_ret.push_back(ret_tool.get_value()); + } + return 0; + } + return -1; + } + static const char* get_typename() { return "vector";} +}; +template +struct pytype_traits_t > +{ + static PyObject* pyobj_from_cppobj(const list& val_) + { + size_t n = val_.size(); + PyObject* ret = PyList_New(n); + int i = 0; + for (typename list::const_iterator it = val_.begin(); it != val_.end(); ++it) + { + PyList_SetItem(ret, i++, pytype_traits_t::pyobj_from_cppobj(*it)); + } + return ret; + } + static int pyobj_to_cppobj(PyObject *pvalue_, list& m_ret) + { + pytype_tool_impl_t ret_tool; + if (true == PyTuple_Check(pvalue_)) + { + int n = PyTuple_Size(pvalue_); + for (int i = 0; i < n; ++i) + { + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyTuple_GetItem(pvalue_, i))) + { + return -1; + } + m_ret.push_back(ret_tool.get_value()); + } + return 0; + } + else if (true == PyList_Check(pvalue_)) + { + int n = PyList_Size(pvalue_); + for (int i = 0; i < n; ++i) + { + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyList_GetItem(pvalue_, i))) + { + return -1; + } + m_ret.push_back(ret_tool.get_value()); + } + return 0; + } + return -1; + } + static const char* get_typename() { return "list";} +}; +template +struct pytype_traits_t > +{ + static PyObject* pyobj_from_cppobj(const set& val_) + { + PyObject* ret = PySet_New(NULL); + for (typename set::const_iterator it = val_.begin(); it != val_.end(); ++it) + { + PyObject *v = pytype_traits_t::pyobj_from_cppobj(*it); + PySet_Add(ret, v); + Py_DECREF(v); + } + return ret; + } + static int pyobj_to_cppobj(PyObject *pvalue_, set& m_ret) + { + m_ret.clear(); + pytype_tool_impl_t ret_tool; + PyObject *iter = PyObject_GetIter(pvalue_); + PyObject *item = NULL; + while (NULL != iter && NULL != (item = PyIter_Next(iter))) + { + T tmp(); + if (pytype_traits_t::pyobj_to_cppobj(item, tmp)) + { + Py_DECREF(item); + Py_DECREF(iter); + return -1; + } + m_ret.insert(tmp); + Py_DECREF(item); + } + if (iter) + { + Py_DECREF(iter); + return 0; + } + return -1; + } + static const char* get_typename() { return "set";} +}; +template +struct pytype_traits_t > +{ + static PyObject* pyobj_from_cppobj(const map& val_) + { + PyObject* ret = PyDict_New(); + for (typename map::const_iterator it = val_.begin(); it != val_.end(); ++it) + { + PyObject *k = pytype_traits_t::pyobj_from_cppobj(it->first); + PyObject *v = pytype_traits_t::pyobj_from_cppobj(it->second); + PyDict_SetItem(ret, k, v); + Py_DECREF(k); + Py_DECREF(v); + } + return ret; + } + static int pyobj_to_cppobj(PyObject *pvalue_, map& m_ret) + { + m_ret.clear(); + pytype_tool_impl_t ret_tool_T; + pytype_tool_impl_t ret_tool_R; + if (true == PyDict_Check(pvalue_)) + { + PyObject *key = NULL, *value = NULL; + Py_ssize_t pos = 0; + + while (PyDict_Next(pvalue_, &pos, &key, &value)) + { + T tmp_key; + R tmp_value; + if (pytype_traits_t::pyobj_to_cppobj(key, tmp_key) || + pytype_traits_t::pyobj_to_cppobj(value, tmp_value)) + { + return -1; + } + m_ret[tmp_key] = tmp_value; + } + return 0; + } + return -1; + } + static const char* get_typename() { return "map";} +}; + +//! ��ȡpython�����ķ���ֵ,������ +template +class pytype_tool_impl_t: public pytype_tool_t +{ +public: + pytype_tool_impl_t():m_ret(){} + + virtual int parse_value(PyObject *pvalue_) + { + if (pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret)) + { + return -1; + } + return 0; + } + + const T& get_value() const { return m_ret; } + virtual const char* return_type() {return pytype_traits_t::get_typename();} +private: + T m_ret; +}; + +template<> +class pytype_tool_impl_t: public pytype_tool_t +{ +public: + pytype_tool_impl_t():m_ret(){} + + virtual int parse_value(PyObject *pvalue_) + { + return 0; + } + + const cpp_void_t& get_value() const { return m_ret; } + virtual const char* return_type() { return "void";} +private: + cpp_void_t m_ret; +}; +template +class pytype_tool_impl_t: public pytype_tool_t +{ +public: + pytype_tool_impl_t():m_ret(){} + + virtual int parse_value(PyObject *pvalue_) + { + if (pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret)) + { + return -1; + } + return 0; + } + + T* get_value() const { return m_ret; } +private: + T* m_ret; +}; + + +template<> +class pytype_tool_impl_t: public pytype_tool_t +{ +public: + pytype_tool_impl_t():m_ret(){} + + virtual int parse_value(PyObject *pvalue_) + { + m_ret = pvalue_; + return 0; + } + + PyObject*& get_value() { return m_ret; } + bool need_release() { return false; } +private: + PyObject* m_ret; +}; + + +template +const T& pycall_t::call(const string& mod_name_, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) +{ + PyObject *pName = NULL, *pModule = NULL; + string err_msg; + + pName = PyString_FromString(mod_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return pyret.get_value(); + } + + call_func(pModule, mod_name_, func_name_, pyarg_, pyret, err_msg); + Py_DECREF(pModule); + + if (!err_msg.empty()) + { + throw runtime_error(err_msg.c_str()); + } + return pyret.get_value(); +} +template +const T& pycall_t::call_obj_method(PyObject *pObj, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) +{ + string err_msg; + if (NULL == pObj) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return pyret.get_value(); + } + + static string mod_name_ = "NaN"; + call_func(pObj, mod_name_, func_name_, pyarg_, pyret, err_msg); + + if (!err_msg.empty()) + { + throw runtime_error(err_msg.c_str()); + } + return pyret.get_value(); +} + +template +const T& pycall_t::call_lambda(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) +{ + string err_msg; + if (NULL == pFunc) + { + err_msg = "can not call null PyObject"; + throw runtime_error(err_msg.c_str()); + return pyret.get_value(); + } + + call_func_obj(pFunc, pyarg_, pyret, err_msg); + + if (!err_msg.empty()) + { + throw runtime_error(err_msg.c_str()); + } + return pyret.get_value(); +} + + +//! 用于扩展python的工具类,用来解析参数 +struct pyext_tool_t +{ + pyext_tool_t(PyObject* args_): + m_args(args_), + m_arg_tuple(NULL), + m_index(0), + m_err(false), + m_func_addr(0) + { + if (!PyArg_ParseTuple(args_, "lO", &m_func_addr, &m_arg_tuple)) { + m_err = true; + return; + } + if (NULL == m_arg_tuple || false == PyTuple_Check(m_arg_tuple)) + { + PyErr_SetString(PyExc_TypeError, "arg type invalid(shoule func_name, args tuple)"); + m_err = true; + return; + } + m_size = PyTuple_Size(m_arg_tuple); + } + + template + pyext_tool_t& parse_arg(T& ret_arg_) + { + //typedef typename type_ref_traits_t::value_t value_t; + if (false == m_err) + { + if (m_index >= m_size) + { + stringstream ss; + ss << "param num invalid, only["<< m_index + 1 <<"] provided"; + PyErr_SetString(PyExc_TypeError, ss.str().c_str()); + m_err = true; + return *this; + } + + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyTuple_GetItem(m_arg_tuple, m_index))) + { + stringstream ss; + ss << "param[" << m_index + 1 << "] type invalid, "<< pytype_traits_t::get_typename() << " needed"; + PyErr_SetString(PyExc_TypeError, ss.str().c_str()); + m_err = true; + return *this; + } + ++m_index; + ret_arg_ = ret_tool.get_value(); + } + return *this; + } + + bool is_err() const { return m_err;} + long get_func_addr() const { return m_func_addr;} + + template + FUNC get_func_ptr() const + { + FUNC f = NULL; + ::memcpy((void*)&f, (const void*)&m_func_addr, sizeof(m_func_addr)); + return f; + } + PyObject* m_args; + PyObject* m_arg_tuple; + int m_index; + int m_size; + bool m_err;//! 是否异常 + long m_func_addr; +}; + + +//! 用于扩展python,生成pyobject类型的返回值给python +template +struct pyext_return_tool_t +{ + //! 用于静态方法 + template + static PyObject* route_call(F f) + { + return pytype_traits_t::pyobj_from_cppobj(f()); + } + template + static PyObject* route_call(F f, ARG1& a1) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value, a8.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value, a8.value, a9.value)); + } + //! 用于成员方法 + template + static PyObject* route_method_call(O o, F f) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)()); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value, a8.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value, a8.value, a9.value)); + } +}; + +template<> +struct pyext_return_tool_t +{ + template + static PyObject* route_call(F f) + { + f(); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1) + { + f(a1.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2) + { + f(a1.value, a2.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3) + { + f(a1.value, a2.value, a3.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) + { + f(a1.value, a2.value, a3.value, a4.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f) + { + (o->*f)(); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1) + { + (o->*f)(a1.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2) + { + (o->*f)(a1.value, a2.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3) + { + (o->*f)(a1.value, a2.value, a3.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); + Py_RETURN_NONE; + } +}; + + +//! 用于扩展python,traits出注册给python的函数接口 +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(); + static int args_num() { return 0;} + static int option_args_num() { return 0;} + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + return pyext_return_tool_t::route_call(f); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1); + static int args_num(){ return 1-option_args_num();} + static int option_args_num() + { + return pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + if (pyext_tool.parse_arg(a1.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2); + static int args_num() { return 2 - option_args_num();} + static int option_args_num() + { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3); + static int args_num() { return 3-option_args_num();} + static int option_args_num() + { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3); + } +}; +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4); + static int args_num() { return 4-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5); + static int args_num() { return 5-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); + static int args_num() { return 6-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); + static int args_num() { return 7-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); + static int args_num() { return 8-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7, a8); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); + static int args_num() { return 9-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + type_ref_traits_t a9; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7, a8, a9); + } +}; + +//! ��������pyclass ��ʼ������ +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + + self->obj = new CLASS_TYPE(); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + if (pyext_tool.parse_arg(a1.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + type_ref_traits_t a9; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); + return 0; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(); + static int args_num() { return 0;} + static int option_args_num() { return 0;} + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1); + static int args_num() { return 1-option_args_num();} + static int option_args_num() { return pyoption_traits_t::value_t>::is();} + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + if (pyext_tool.parse_arg(a1.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2); + static int args_num() { return 2-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2);; + } +}; + + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3); + static int args_num() { return 3-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4); + static int args_num() { return 4-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5); + static int args_num() { return 5-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); + static int args_num() { return 6-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); + static int args_num() { return 7-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); + static int args_num() { return 8-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8);; + } +}; + + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); + static int args_num() { return 9-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + type_ref_traits_t a9; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8, a9);; + } +}; + +//! const类型成员函数--------------------------------------------------------------------------------------------- + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)() const; + static int args_num() { return 0;} + static int option_args_num() { return 0;} + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1) const; + static int args_num() { return 1-option_args_num();} + static int option_args_num() { return pyoption_traits_t::value_t>::is();} + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + if (pyext_tool.parse_arg(a1.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2) const; + static int args_num() { return 2-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2);; + } +}; + + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3) const; + static int args_num() { return 3-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4) const; + static int args_num() { return 4-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5) const; + static int args_num() { return 5-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) const; + static int args_num() { return 6-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) const; + static int args_num() { return 7-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8) const; + static int args_num() { return 8-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8);; + } +}; + + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9) const; + static int args_num() { return 9-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + type_ref_traits_t a9; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8, a9);; + } +}; + +#endif diff --git a/vs2008.x86/ffpython.vcxproj b/vs2008.x86/ffpython.vcxproj new file mode 100644 index 0000000..1dcff00 --- /dev/null +++ b/vs2008.x86/ffpython.vcxproj @@ -0,0 +1,177 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {A7E1C195-DF68-4713-A758-E27C6E02858C} + ffpython + Win32Proj + 10.0.17763.0 + + + + Application + v141 + Unicode + true + + + Application + v141 + Unicode + true + + + Application + v141 + Unicode + + + Application + v141 + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.28127.55 + + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + + + true + + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + + + false + + + + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + Level3 + EditAndContinue + + + true + Console + MachineX86 + + + + + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + C:\Users\zhaoxinfeng.evan\AppData\Local\Programs\Python\Python37\include;%(AdditionalIncludeDirectories) + + + true + Console + C:\Users\zhaoxinfeng.evan\AppData\Local\Programs\Python\Python37\libs;%(AdditionalLibraryDirectories) + + + + + MaxSpeed + true + ../;C:\Users\zhaoxinfeng.evan\AppData\Local\Programs\Python\Python37\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + Level3 + ProgramDatabase + + + python3.lib;%(AdditionalDependencies) + C:\Python27\libs;C:\Users\zhaoxinfeng.evan\AppData\Local\Programs\Python\Python37\Libs;%(AdditionalLibraryDirectories) + true + Console + true + true + MachineX64 + + + + + MaxSpeed + true + ../;C:\Users\zhaoxinfeng.evan\AppData\Local\Programs\Python\Python37\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + python3.lib;%(AdditionalDependencies) + C:\Python27\libs;C:\Users\zhaoxinfeng.evan\AppData\Local\Programs\Python\Python37\Libs;%(AdditionalLibraryDirectories) + true + Console + true + true + + + + + + + + + + + + + + + + \ No newline at end of file From 81d0c70bb36fc8da535c76166537a59f0a44bff3 Mon Sep 17 00:00:00 2001 From: fanchy Date: Tue, 22 Oct 2019 20:17:17 +0800 Subject: [PATCH 02/13] support pythonV3 --- Makefile | 2 +- VersionForRead/ffpython.cpp | 568 ----- VersionForRead/ffpython.h | 481 ---- VersionForRead/pyops_base.h | 1123 --------- VersionForRead/pyops_for_embed.h | 77 - VersionForRead/pyops_for_extend.h | 1745 -------------- example.cpp | 145 +- ffpython.h | 3595 +---------------------------- fftest.py | 21 +- vs2008.x86/ffpython.ncb | Bin 2919424 -> 0 bytes vs2008.x86/ffpython.sln | 17 +- vs2008.x86/ffpython.suo | Bin 9728 -> 0 bytes 12 files changed, 183 insertions(+), 7591 deletions(-) delete mode 100644 VersionForRead/ffpython.cpp delete mode 100644 VersionForRead/ffpython.h delete mode 100644 VersionForRead/pyops_base.h delete mode 100644 VersionForRead/pyops_for_embed.h delete mode 100644 VersionForRead/pyops_for_extend.h delete mode 100644 vs2008.x86/ffpython.ncb delete mode 100644 vs2008.x86/ffpython.suo diff --git a/Makefile b/Makefile index 814d0a2..12af8d9 100644 --- a/Makefile +++ b/Makefile @@ -3,4 +3,4 @@ .PHONY:all all: - g++ -o app_test example.cpp -I /usr/include/python2.6/ -L /usr/lib64/ -lpython2.6 + g++ -o app_test example.cpp -I /usr/include/python2.7/ -L /usr/lib64/ -lpython2.7 diff --git a/VersionForRead/ffpython.cpp b/VersionForRead/ffpython.cpp deleted file mode 100644 index c78bf09..0000000 --- a/VersionForRead/ffpython.cpp +++ /dev/null @@ -1,568 +0,0 @@ -#include "ffpython.h" - - -//! 获取python异常信息 - -int pyops_t::traceback(string& ret_) -{ - PyObject* err = PyErr_Occurred(); - - if (err != NULL) { - PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL; - PyObject *pyth_module = NULL, *pyth_func = NULL; - - PyErr_Fetch(&ptype, &pvalue, &ptraceback); - if (pvalue) - { - if (true == PyList_Check(pvalue)) - { - int n = PyList_Size(pvalue); - for (int i = 0; i < n; ++i) - { - PyObject *pystr = PyObject_Str(PyList_GetItem(pvalue, i)); - ret_ += PyString_AsString(pystr); - ret_ += "\n"; - Py_DECREF(pystr); - } - } - if (true == PyTuple_Check(pvalue)) - { - int n = PyTuple_Size(pvalue); - for (int i = 0; i < n; ++i) - { - PyObject* tmp_str = PyTuple_GetItem(pvalue, i); - if (true == PyTuple_Check(tmp_str)) - { - int m = PyTuple_Size(tmp_str); - for (int j = 0; j < m; ++j) - { - PyObject *pystr = PyObject_Str(PyTuple_GetItem(tmp_str, j)); - ret_ += PyString_AsString(pystr); - ret_ += ","; - Py_DECREF(pystr); - } - } - else - { - PyObject *pystr = PyObject_Str(tmp_str); - ret_ += PyString_AsString(pystr); - Py_DECREF(pystr); - } - ret_ += "\n"; - } - } - else - { - PyObject *pystr = PyObject_Str(pvalue); - if (pystr) - { - ret_ += PyString_AsString(pystr); - ret_ += "\n"; - Py_DECREF(pystr); - } - } - } - - /* See if we can get a full traceback */ - PyObject *module_name = PyString_FromString("traceback"); - pyth_module = PyImport_Import(module_name); - Py_DECREF(module_name); - - if (pyth_module && ptype && pvalue && ptraceback) - { - pyth_func = PyObject_GetAttrString(pyth_module, "format_exception"); - if (pyth_func && PyCallable_Check(pyth_func)) { - PyObject *pyth_val = PyObject_CallFunctionObjArgs(pyth_func, ptype, pvalue, ptraceback, NULL); - if (pyth_val && true == PyList_Check(pyth_val)) - { - int n = PyList_Size(pyth_val); - for (int i = 0; i < n; ++i) - { - PyObject* tmp_str = PyList_GetItem(pyth_val, i); - PyObject *pystr = PyObject_Str(tmp_str); - if (pystr) - { - ret_ += PyString_AsString(pystr); - - Py_DECREF(pystr); - } - ret_ += "\n"; - } - } - Py_XDECREF(pyth_val); - } - } - Py_XDECREF(pyth_func); - Py_XDECREF(pyth_module); - Py_XDECREF(ptype); - Py_XDECREF(pvalue); - Py_XDECREF(ptraceback); - PyErr_Clear(); - return 0; - } - - return -1; -} - - -ffpython_t::ffpython_t() -{ - if (!Py_IsInitialized()) - Py_Initialize(); -} -ffpython_t::~ffpython_t() -{ - clear_cache_pyobject(); -} - - -int ffpython_t::init_py() -{ - Py_Initialize(); - return 0; -} -int ffpython_t::final_py() -{ - Py_Finalize(); - return 0; -} - -int ffpython_t::add_path(const string& path_) -{ - char buff[1024]; - SAFE_SPRINTF(buff, sizeof(buff), "import sys\nif '%s' not in sys.path:\n\tsys.path.append('%s')\n", path_.c_str(), path_.c_str()); - PyRun_SimpleString(buff); - return 0; -} - -int ffpython_t::run_string(const string& py_) -{ - PyRun_SimpleString(py_.c_str()); - return 0; -} - -int ffpython_t::reload(const string& py_name_) -{ - PyObject *pName = NULL, *pModule = NULL; - string err_msg; - - pName = PyString_FromString(py_name_.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - return -1; - } - - PyObject *pNewMod = PyImport_ReloadModule(pModule); - Py_DECREF(pModule); - if (NULL == pNewMod) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - return -1; - } - Py_DECREF(pNewMod); - return 0; -} -int ffpython_t::load(const string& py_name_) -{ - PyObject *pName = NULL, *pModule = NULL; - string err_msg; - - pName = PyString_FromString(py_name_.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - return -1; - } - - Py_DECREF(pModule); - return 0; -} - -int ffpython_t::init(const string& mod_name_, string doc_) -{ - m_mod_name = mod_name_; - m_mod_doc = doc_; - PyObject* m = init_method(); - init_pyclass(m); - return 0; -} - -PyObject* ffpython_t::init_method() -{ - string mod_name_ = m_mod_name; - string doc_ = m_mod_doc; - - if (m_pymethod_defs.empty()) - { - m_pymethod_defs.reserve(m_func_info.size() + 1); - - for (size_t i = 0; i < m_func_info.size(); ++i) - { - PyMethodDef tmp = {m_func_info[i].func_impl_name.c_str(), m_func_info[i].func, - METH_VARARGS, m_func_info[i].doc_impl.c_str()}; - m_pymethod_defs.push_back(tmp); - } - PyMethodDef tmp = {NULL}; - m_pymethod_defs.push_back(tmp); - } - - PyObject* m = Py_InitModule3(m_mod_name.c_str(), &(m_pymethod_defs.front()), doc_.c_str()); - - for (size_t i = 0; i < m_func_info.size(); ++i) - { - string pystr_args; - string pystr_args_only_name; - for (int j = 0; j < m_func_info[i].args_num; ++j) - { - stringstream ss; - if (pystr_args.empty()) - { - ss << "a" << (j+1); - pystr_args += ss.str(); - } - else - { - ss << ", a" << (j+1); - pystr_args += ss.str(); - } - } - pystr_args_only_name = pystr_args; - for (int j = 0; j < m_func_info[i].option_args_num; ++j) - { - stringstream ss; - if (pystr_args.empty()) - { - ss << "a" << (m_func_info[i].args_num + j+1); - string tmp = ss.str(); - pystr_args_only_name += tmp; - pystr_args += tmp + " = None"; - } - else - { - ss << ", a" << (m_func_info[i].args_num + j+1); - string tmp = ss.str(); - pystr_args_only_name += tmp; - pystr_args += tmp + " = None"; - } - } - if (!pystr_args_only_name.empty()) - pystr_args_only_name += ","; - - char buff[1024]; - SAFE_SPRINTF(buff, sizeof(buff), - "_tmp_ff_ = None\nif '%s' in globals():\n\t_tmp_ff_ = globals()['%s']\n" - "def %s(%s):\n" - "\t'''%s'''\n" - "\treturn %s.%s(%ld,(%s))\n" - "import %s\n" - "%s.%s = %s\n" - "%s = None\n" - "if _tmp_ff_:\n\tglobals()['%s'] = _tmp_ff_\n_tmp_ff_ = None\n", - m_func_info[i].func_name.c_str(), m_func_info[i].func_name.c_str(), - m_func_info[i].func_name.c_str(), pystr_args.c_str(), - m_func_info[i].doc.c_str(), - m_mod_name.c_str(), m_func_info[i].func_impl_name.c_str(), m_func_info[i].func_addr, pystr_args_only_name.c_str(), - m_mod_name.c_str(), - m_mod_name.c_str(), m_func_info[i].func_name.c_str(), m_func_info[i].func_name.c_str(), - m_func_info[i].func_name.c_str(), - m_func_info[i].func_name.c_str() - ); - - //printf(buff); - PyRun_SimpleString(buff); - } - - return m; -} - -int ffpython_t::init_pyclass(PyObject* m) -{ - for (size_t i = 0; i < m_all_pyclass.size(); ++i) - { - m_all_pyclass[i].static_pytype_info->mod_name = m_mod_name; - if (false == m_all_pyclass[i].inherit_name.empty()) - { - pyclass_regigster_tool_t* inherit_class = get_pyclass_info_by_name(m_all_pyclass[i].inherit_name); - assert(inherit_class && "base class must be registed"); - for (size_t n = 0; n < inherit_class->methods_info.size(); ++n) - { - const string& method_name = inherit_class->methods_info[n].func_name; - if (false == is_method_exist(m_all_pyclass[i].methods_info, method_name)) - { - m_all_pyclass[i].methods_info.push_back(inherit_class->methods_info[n]); - } - } - for (size_t n = 0; n < inherit_class->propertys_info.size(); ++n) - { - const string& property_name = inherit_class->propertys_info[n].property_name; - if (false == is_property_exist(m_all_pyclass[i].propertys_info, property_name)) - { - m_all_pyclass[i].propertys_info.push_back(inherit_class->propertys_info[n]); - } - } - } - //! init class property - for (size_t j = 0; j < m_all_pyclass[i].propertys_info.size(); ++j) - { - PyGetSetDef tmp = {(char*)m_all_pyclass[i].propertys_info[j].property_name.c_str(), - m_all_pyclass[i].propertys_info[j].getter_func, - m_all_pyclass[i].propertys_info[j].setter_func, - (char*)m_all_pyclass[i].propertys_info[j].doc.c_str(), - m_all_pyclass[i].propertys_info[j].ptr - }; - m_all_pyclass[i].pyproperty_def.push_back(tmp); - } - PyGetSetDef tmp_property_def = {NULL}; - m_all_pyclass[i].pyproperty_def.push_back(tmp_property_def); - //! init class method - for (size_t j = 0; j < m_all_pyclass[i].methods_info.size(); ++j) - { - PyMethodDef tmp = {m_all_pyclass[i].methods_info[j].func_real_name.c_str(), - m_all_pyclass[i].methods_info[j].func, - METH_VARARGS, - m_all_pyclass[i].methods_info[j].doc.c_str() - }; - m_all_pyclass[i].pymethod_def.push_back(tmp); - - } - PyMethodDef tmp_del = {"delete", - m_all_pyclass[i].delete_func, - METH_VARARGS, - "delete obj" - }; - m_all_pyclass[i].pymethod_def.push_back(tmp_del); - PyMethodDef tmp_method_def = {NULL}; - m_all_pyclass[i].pymethod_def.push_back(tmp_method_def); - - m_all_pyclass[i].class_name_with_mod = m_mod_name + "." + m_all_pyclass[i].class_name; - m_all_pyclass[i].class_reel_name_with_mod = m_mod_name + "." + m_all_pyclass[i].class_real_name; - - PyTypeObject tmp_pytype_def = - { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - m_all_pyclass[i].class_reel_name_with_mod.c_str(), /*tp_name*/ - m_all_pyclass[i].type_size, /*tp_size*/ - 0, /*tp_itemsize*/ - (destructor)m_all_pyclass[i].dector, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - m_all_pyclass[i].doc.c_str(), /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - &(m_all_pyclass[i].pymethod_def.front()),//Noddy_methods, /* tp_methods */ - 0,//Noddy_members, /* tp_members */ - &(m_all_pyclass[i].pyproperty_def.front()),//Noddy_getseters, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)m_all_pyclass[i].init, /* tp_init */ - 0, /* tp_alloc */ - m_all_pyclass[i].ctor, /* tp_new */ - }; - m_all_pyclass[i].pytype_def = tmp_pytype_def; - m_all_pyclass[i].static_pytype_info->pytype_def = &m_all_pyclass[i].pytype_def; - cpp_to_pyclass_reg_info_t::add(m_all_pyclass[i].class_name, m_all_pyclass[i].inherit_name, &m_all_pyclass[i].pytype_def); - - if (PyType_Ready(&(m_all_pyclass[i].pytype_def)) < 0) - return -1; - PyObject* tmpP = (PyObject*)(&(m_all_pyclass[i].pytype_def)); - Py_INCREF(tmpP); - PyModule_AddObject(m, m_all_pyclass[i].class_real_name.c_str(), (PyObject *)&m_all_pyclass[i].pytype_def); - - stringstream str_def_args; - stringstream str_init_args; - for (int a = 0; a < m_all_pyclass[i].args_num; ++a) - { - str_def_args << "a"<<(a+1)<<","; - str_init_args << "a"<<(a+1)<<","; - } - for (int b = 0; b < m_all_pyclass[b].option_args_num; ++b) - { - str_def_args << "a"<<(m_all_pyclass[i].args_num+ b+1)<<" = None,"; - str_init_args << "a"<<(m_all_pyclass[i].args_num+ b+1)<<","; - } - - char buff[1024]; - SAFE_SPRINTF(buff, sizeof(buff), - "_tmp_ff_ = None\nif '%s' in globals():\n\t_tmp_ff_ = globals()['%s']\n" - "import %s\n" - "class %s(object):\n" - "\t'''%s'''\n" - "\tdef __init__(self, %s assign_obj_ = 0):\n"//! ����init���� - "\t\t'''%s'''\n" - "\t\tif True == isinstance(assign_obj_, %s):\n" - "\t\t\tself.obj = assign_obj_\n" - "\t\t\treturn\n" - "\t\tself.obj = %s(0,(%s))\n", - m_all_pyclass[i].class_name.c_str(), m_all_pyclass[i].class_name.c_str(), - m_mod_name.c_str(), - m_all_pyclass[i].class_name.c_str(), - m_all_pyclass[i].doc.c_str(), - str_def_args.str().c_str(), - "init class", - m_all_pyclass[i].class_reel_name_with_mod.c_str(), - m_all_pyclass[i].class_reel_name_with_mod.c_str(), str_init_args.str().c_str() - ); - - string gen_class_str = buff; - SAFE_SPRINTF(buff, sizeof(buff), - "\tdef delete(self):\n" - "\t\t'''delete obj'''\n" - "\t\tself.obj.delete()\n"); - gen_class_str += buff; - //! 增加析构函数 - //! 增加属性 - for (size_t c = 0; c < m_all_pyclass[i].propertys_info.size(); ++c) - { - SAFE_SPRINTF(buff, sizeof(buff), - "\tdef get_%s(self):\n" - "\t\treturn self.obj.%s\n" - "\tdef set_%s(self, v):\n" - "\t\tself.obj.%s = v\n" - "\t@property\n" - "\tdef %s(self):\n" - "\t\treturn self.obj.%s\n" - "\t@%s.setter\n" - "\tdef %s(self, v):\n" - "\t\tself.obj.%s = v\n", - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str() - ); - gen_class_str += buff; - } - - for (size_t m = 0; m < m_all_pyclass[i].methods_info.size(); ++m) - { - string pystr_args; - string pystr_args_only_name; - for (int j = 0; j < m_all_pyclass[i].methods_info[m].args_num; ++j) - { - stringstream ss; - if (pystr_args.empty()) - { - ss << "a" << (j+1); - pystr_args += ss.str(); - } - else - { - ss << ", a" << (j+1); - pystr_args += ss.str(); - } - } - pystr_args_only_name = pystr_args; - for (int j = 0; j < m_all_pyclass[i].methods_info[m].option_args_num; ++j) - { - stringstream ss; - if (pystr_args.empty()) - { - ss << "a" << (m_all_pyclass[i].methods_info[m].args_num + j+1); - string tmp = ss.str(); - pystr_args_only_name += tmp; - pystr_args += tmp + " = None"; - } - else - { - ss << ", a" << (m_all_pyclass[i].methods_info[m].args_num + j+1); - string tmp = ss.str(); - pystr_args_only_name += tmp; - pystr_args += tmp + " = None"; - } - } - if (!pystr_args_only_name.empty()) - pystr_args_only_name += ","; - - SAFE_SPRINTF(buff, sizeof(buff), - "\tdef %s(self,%s):\n" - "\t\t'''%s'''\n" - "\t\treturn self.obj.%s(%ld,(%s))\n" - ,m_all_pyclass[i].methods_info[m].func_name.c_str(), pystr_args.c_str(), - m_all_pyclass[i].methods_info[m].doc.c_str(), - m_all_pyclass[i].methods_info[m].func_real_name.c_str(), m_all_pyclass[i].methods_info[m].func_addr, pystr_args_only_name.c_str() - ); - gen_class_str += buff; - } - SAFE_SPRINTF(buff, sizeof(buff), - "%s.%s = %s\n" - "%s = None\n" - "if _tmp_ff_:\n\tglobals()['%s'] = _tmp_ff_\n_tmp_ff_ = None\n", - m_mod_name.c_str(), m_all_pyclass[i].class_name.c_str(), m_all_pyclass[i].class_name.c_str(), - m_all_pyclass[i].class_name.c_str(), - m_all_pyclass[i].class_name.c_str() - ); - gen_class_str += buff; - //printf(gen_class_str.c_str()); - PyRun_SimpleString(gen_class_str.c_str()); - } - return 0; -} - - -bool ffpython_t::is_method_exist(const vector& src_, const string& new_) -{ - for (size_t i = 0; i < src_.size(); ++i) - { - if (new_ == src_[i].func_name) - { - return true; - } - } - return false; -} -bool ffpython_t::is_property_exist(const vector& src_, const string& new_) -{ - for (size_t i = 0; i < src_.size(); ++i) - { - if (new_ == src_[i].property_name) - { - return true; - } - } - return false; -} -pyclass_regigster_tool_t* ffpython_t::get_pyclass_info_by_name(const string& name_) -{ - for (size_t i = 0; i < m_all_pyclass.size(); ++i) - { - if (m_all_pyclass[i].class_name == name_) - { - return &(m_all_pyclass[i]); - } - } - return NULL; -} - diff --git a/VersionForRead/ffpython.h b/VersionForRead/ffpython.h deleted file mode 100644 index 5585f5f..0000000 --- a/VersionForRead/ffpython.h +++ /dev/null @@ -1,481 +0,0 @@ -#ifndef __FFPYTHON_H_ -#define __FFPYTHON_H_ - -#include -#include - -#include -using namespace std; - -#include "pyops_base.h" -#include "pyops_for_embed.h" -#include "pyops_for_extend.h" - -class ffpython_t -{ - struct reg_info_t - { - reg_info_t():args_num(0),option_args_num(0),func_addr(0){} - int args_num; - int option_args_num; - long func_addr; - PyCFunction func; - string func_name; - string func_impl_name; - string doc; - string doc_impl; - }; - -public: - ffpython_t(); - ~ffpython_t(); - - static int init_py(); - static int final_py(); - - static int add_path(const string& path_); - - static int run_string(const string& py_); - static int reload(const string& py_name_); - static int load(const string& py_name_); - - - //! 将需要注册的函数、类型注册到python虚拟机 - int init(const string& mod_name_, string doc_ = ""); - - //! 注册static function, - template - ffpython_t& reg(T func_, const string& func_name_, string doc_ = "") - { - reg_info_t tmp; - tmp.args_num = pyext_func_traits_t::args_num(); - tmp.option_args_num = pyext_func_traits_t::option_args_num(); - tmp.func = (PyCFunction)pyext_func_traits_t::pyfunc; - tmp.func_name= func_name_; - tmp.func_impl_name = func_name_ + "_internal_"; - tmp.doc = doc_; - tmp.doc_impl = string("internal use, please call ") + func_name_; - tmp.func_addr= (long)func_; - - m_func_info.push_back(tmp); - return *this; - } - - //! 注册c++ class - template - pyclass_regigster_tool_t& reg_class(const string& class_name_, string doc_ = "", string inherit_name_ = "") - { - if (pyclass_base_info_t::pytype_info.class_name.empty() == false) - throw runtime_error("this type has been registed"); - - pyclass_base_info_t::pytype_info.class_name = class_name_; - //pyclass_base_info_t::pytype_info.mod_name = m_mod_name; - pyclass_base_info_t::pytype_info.total_args_num = pyext_func_traits_t::args_num() + - pyext_func_traits_t::option_args_num(); - - pyclass_regigster_tool_t tmp; - tmp.class_name = class_name_; - tmp.class_real_name = class_name_ + "_internal_"; - tmp.inherit_name = inherit_name_; - tmp.doc = doc_; - tmp.dector = (destructor)pyclass_base_info_t::free_obj; - tmp.init = (initproc)pyclass_ctor_tool_t::init_obj; - tmp.ctor = pyclass_base_info_t::alloc_obj; - tmp.type_size = sizeof(typename pyclass_base_info_t::obj_data_t); - tmp.args_num = pyext_func_traits_t::args_num(); - tmp.option_args_num = pyext_func_traits_t::option_args_num(); - tmp.static_pytype_info = &(pyclass_base_info_t::pytype_info); - //! 注册析构函数,python若不调用析构函数,当对象被gc时自动调用 - tmp.delete_func = (PyCFunction)pyclass_base_info_t::release; - m_all_pyclass.push_back(tmp); - - return m_all_pyclass.back(); - } - - - //! 调用python函数,最多支持9个参数 - template - RET_V call(const string& mod_name_, const string& func_) - { - pycall_arg_t args(0); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1) - { - pycall_arg_t args(1); - args.add(a1); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2) - { - pycall_arg_t args(2); - args.add(a1).add(a2); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3) - { - pycall_arg_t args(3); - args.add(a1).add(a2).add(a3); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) - { - pycall_arg_t args(4); - args.add(a1).add(a2).add(a3).add(a4); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5) - { - pycall_arg_t args(5); - args.add(a1).add(a2).add(a3).add(a4).add(a5); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5,const ARG6& a6) - { - pycall_arg_t args(6); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5,const ARG6& a6,const ARG7& a7) - { - pycall_arg_t args(7); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) - { - pycall_arg_t args(8); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) - { - pycall_arg_t args(9); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8).add(a9); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - //!call python class method begin****************************************************************** - template - RET_V obj_call(PyObject* pobj, const string& func_) - { - pycall_arg_t args(0); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1) - { - pycall_arg_t args(1); - args.add(a1); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2) - { - pycall_arg_t args(2); - args.add(a1).add(a2); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3) - { - pycall_arg_t args(3); - args.add(a1).add(a2).add(a3); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) - { - pycall_arg_t args(4); - args.add(a1).add(a2).add(a3).add(a4); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5) - { - pycall_arg_t args(5); - args.add(a1).add(a2).add(a3).add(a4).add(a5); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5,const ARG6& a6) - { - pycall_arg_t args(6); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5,const ARG6& a6,const ARG7& a7) - { - pycall_arg_t args(7); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) - { - pycall_arg_t args(8); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) - { - pycall_arg_t args(9); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8).add(a9); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - //!call python class method end****************************************************************** - - //!call python lambad function begin ############################################################ - template - RET_V call_lambda(PyObject* pobj) - { - pycall_arg_t args(0); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1) - { - pycall_arg_t args(1); - args.add(a1); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2) - { - pycall_arg_t args(2); - args.add(a1).add(a2); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3) - { - pycall_arg_t args(3); - args.add(a1).add(a2).add(a3); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) - { - pycall_arg_t args(4); - args.add(a1).add(a2).add(a3).add(a4); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5) - { - pycall_arg_t args(5); - args.add(a1).add(a2).add(a3).add(a4).add(a5); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5,const ARG6& a6) - { - pycall_arg_t args(6); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5,const ARG6& a6,const ARG7& a7) - { - pycall_arg_t args(7); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) - { - pycall_arg_t args(8); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) - { - pycall_arg_t args(9); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8).add(a9); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - //!call python lambad function ennd ############################################################ - template - RET_V get_global_var(const string& mod_name_, const string& var_name_) - { - PyObject *pName = NULL, *pModule = NULL; - string err_msg; - - pName = PyString_FromString(mod_name_.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - } - - pytype_tool_impl_t pyret; - PyObject *pvalue = PyObject_GetAttrString(pModule, var_name_.c_str()); - Py_DECREF(pModule); - - if (!pvalue) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - } - - if (pyret.parse_value(pvalue)) - { - Py_XDECREF(pvalue); - throw runtime_error("type invalid"); - } - Py_XDECREF(pvalue); - return pyret.get_value(); - } - - template - int set_global_var(const string& mod_name_, const string& var_name_, const T& val_) - { - PyObject *pName = NULL, *pModule = NULL; - string err_msg; - - pName = PyString_FromString(mod_name_.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - } - - PyObject* pval = pytype_traits_t::pyobj_from_cppobj(val_); - int ret = PyObject_SetAttrString(pModule, var_name_.c_str(), pval); - Py_DECREF(pModule); - - return ret != -1? 0: -1; - } - - template - RET_V getattr(PyObject* pModule, const string& var_name_) - { - string err_msg; - if (NULL == pModule) - { - throw runtime_error("getattr object ptr null"); - } - - pytype_tool_impl_t pyret; - PyObject *pvalue = PyObject_GetAttrString(pModule, var_name_.c_str()); - - if (!pvalue) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - } - - if (pyret.parse_value(pvalue)) - { - Py_XDECREF(pvalue); - throw runtime_error("type invalid"); - } - Py_XDECREF(pvalue); - return pyret.get_value(); - } - - - void cache_pyobject(PyObject* pobj) - { - m_cache_pyobject.push_back(pobj); - } - void clear_cache_pyobject() - { - if (Py_IsInitialized()) - { - for (size_t i = 0; i < m_cache_pyobject.size(); ++i) - { - Py_XDECREF(m_cache_pyobject[i]); - } - m_cache_pyobject.clear(); - } - } -private: - PyObject* init_method(); - int init_pyclass(PyObject* m); - - - bool is_method_exist(const vector& src_, const string& new_); - bool is_property_exist(const vector& src_, const string& new_); - pyclass_regigster_tool_t* get_pyclass_info_by_name(const string& name_); - -private: - string m_mod_name; - string m_mod_doc; - vector m_pymethod_defs; - vector m_func_info; - - //! reg class - vector m_all_pyclass; - //! cache some pyobject for optimize - vector m_cache_pyobject; -}; - - -#endif diff --git a/VersionForRead/pyops_base.h b/VersionForRead/pyops_base.h deleted file mode 100644 index ccb0f5c..0000000 --- a/VersionForRead/pyops_base.h +++ /dev/null @@ -1,1123 +0,0 @@ -#ifndef __PYOPS_BASE_ -#define __PYOPS_BASE_ - - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -#ifdef _WIN32 -#define SAFE_SPRINTF _snprintf_s -#else -#define SAFE_SPRINTF snprintf -#endif - - - -//! 获取python异常信息 -struct pyops_t -{ - static int traceback(string& ret_); -}; -struct cpp_void_t{}; - -//! 用于抽取类型、类型对应的引用 -template -struct type_ref_traits_t; - -//! 用于python 可选参数 -template -struct pyoption_t -{ - typedef typename type_ref_traits_t::value_t value_t; - pyoption_t():m_set_flag(false){} - bool is_set() const { return m_set_flag;} - void set() { m_set_flag = true;} - value_t& value() { return m_value;} - const value_t& value() const{ return m_value;} - - const value_t& value(const value_t& default_) - { - if (is_set()) - return m_value; - else - return default_; - } - bool m_set_flag; - value_t m_value; -}; -//! 用于判断是否是可选参数 -template -struct pyoption_traits_t; - -//! pytype_traits_t 封装 PyLong_FromLong 相关的操作,用于为调用python生成参数 -template -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const char* const val_) - { - return PyString_FromString(val_); - } - /* - static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) - { - if (true == PyString_Check(pvalue_)) - { - m_ret = PyString_AsString(pvalue_); - return 0; - } - return -1; - } - */ - static const char* get_typename() { return "string";} -}; - -//! 用于调用python函数,生成tuple类型的python函数参数的工具类 -struct pycall_arg_t -{ - pycall_arg_t(int arg_num): - arg_index(0), - pargs_tuple(PyTuple_New(arg_num)) - {} - ~pycall_arg_t() - { - release(); - } - PyObject * get_args() const - { - return pargs_tuple; - } - template - pycall_arg_t& add(const T& val_) - { - if (arg_index < PyTuple_Size(pargs_tuple)) - { - PyObject* tmp_arg = pytype_traits_t::pyobj_from_cppobj(val_); - PyTuple_SetItem(pargs_tuple, arg_index, tmp_arg); - ++arg_index; - } - return *this; - } - void release() - { - if (pargs_tuple) - { - Py_DECREF(pargs_tuple); - pargs_tuple = NULL; - } - } - int arg_index; - PyObject * pargs_tuple; -}; - -//! 用于调用python函数,获取返回值的工具类 -class pytype_tool_t -{ -public: - virtual ~pytype_tool_t(){}; - virtual int parse_value(PyObject *pvalue_) = 0; - virtual const char* return_type() {return "";} - virtual bool need_release() { return false; } -}; - -//! 用于调用python函数,获取返回值的工具泛型类 -template -class pytype_tool_impl_t; -//! 封装调用python函数的C API -struct pycall_t -{ - static int call_func(PyObject *pModule, const string& mod_name_, const string& func_name_, - pycall_arg_t& pyarg_, pytype_tool_t& pyret_, string& err_) - { - PyObject *pFunc = PyObject_GetAttrString(pModule, func_name_.c_str()); - if (pFunc && PyCallable_Check(pFunc)) { - PyObject *pArgs = pyarg_.get_args(); - PyObject *pValue = PyObject_CallObject(pFunc, pArgs); - pyarg_.release();//! 等价于Py_DECREF(pArgs); - - if (pValue != NULL) { - if (pyret_.parse_value(pValue)) - { - err_ += "value returned is not "; - err_ += pyret_.return_type(); - err_ += string(" ") + func_name_ + " in " + mod_name_; - } - if (pyret_.need_release()){ - Py_DECREF(pValue); - } - } - } - else - { - err_ += "Cannot find function "; - err_ += func_name_ + " in " + mod_name_ + ","; - } - - Py_XDECREF(pFunc); - if (PyErr_Occurred()) - { - pyops_t::traceback(err_); - return 0; - } - return 0; - } - static int call_func_obj(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_t& pyret_, string& err_) - { - if (pFunc && PyCallable_Check(pFunc)) { - PyObject *pArgs = pyarg_.get_args(); - PyObject *pValue = PyObject_CallObject(pFunc, pArgs); - pyarg_.release();//! 等价于Py_DECREF(pArgs); - - if (pValue != NULL) { - if (pyret_.parse_value(pValue)) - { - err_ += "value returned is not "; - err_ += pyret_.return_type(); - } - if (pyret_.need_release()){ - Py_DECREF(pValue); - } - } - } - else - { - err_ += "invalid function"; - } - - if (PyErr_Occurred()) - { - pyops_t::traceback(err_); - return 0; - } - return 0; - } - template - static const T& call(const string& mod_name_, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); - template - static const T& call_obj_method(PyObject *pObj, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); - template - static const T& call_lambda(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); -}; -//! 用于扩展python的工具类,用来解析参数 -struct pyext_tool_t; - - -template -struct pyext_return_tool_t; - -//! 用于扩展python,生成pyobject类型的返回值给python -template -struct pyext_func_traits_t; - -//! 用于扩展python,traits出注册给python的函数接口 -#ifndef PYCTOR -#define PYCTOR int (*) -#endif -//! 表示void类型,由于void类型不能return,用void_ignore_t适配 -template -struct void_ignore_t; - -template -struct void_ignore_t -{ - typedef T value_t; -}; - -template<> -struct void_ignore_t -{ - typedef cpp_void_t value_t; -}; - -#define RET_V typename void_ignore_t::value_t - -//! 记录各个基类和子类的相互关系 -struct cpp_to_pyclass_reg_info_t -{ - struct inherit_info_t - { - inherit_info_t():pytype_def(NULL){} - PyTypeObject* pytype_def; - string inherit_name; - set all_child; - }; - typedef map inherit_info_map_t; - static inherit_info_map_t& get_all_info() - { - static inherit_info_map_t inherit_info; - return inherit_info; - } - - static void add(const string& child_, const string& base_, PyTypeObject* def_) - { - inherit_info_t tmp; - tmp.inherit_name = base_; - tmp.pytype_def = def_; - get_all_info()[child_] = tmp; - get_all_info()[base_].all_child.insert(def_); - } - static bool is_instance(PyObject* pysrc, const string& class_) - { - inherit_info_map_t& inherit_info = get_all_info(); - inherit_info_t& tmp = inherit_info[class_]; - if (tmp.pytype_def && PyObject_TypeCheck(pysrc, tmp.pytype_def)) - { - return true; - } - for (set::iterator it = tmp.all_child.begin(); it != tmp.all_child.end(); ++it) - { - if (*it && PyObject_TypeCheck(pysrc, *it)) - { - return true; - } - } - - return false; - } - -}; - - -//! 记录C++ class 对应到python中的名称、参数信息等,全局 -struct static_pytype_info_t -{ - string class_name; - string mod_name; - int total_args_num; - PyTypeObject* pytype_def; -}; - -//! 工具类,用于生成分配python class的接口,包括分配、释放 -template -struct pyclass_base_info_t -{ - struct obj_data_t - { - obj_data_t():obj(NULL){} - - PyObject_HEAD; - T* obj; - bool forbid_release; - void disable_auto_release(){ forbid_release = true; } - void release() - { - if (obj) - { - delete obj; - obj = NULL; - } - } - }; - - static void free_obj(obj_data_t* self) - { - if (false == self->forbid_release && self->obj) - { - self->release(); - } - self->ob_type->tp_free((PyObject*)self); - } - - static PyObject *alloc_obj(PyTypeObject *type, PyObject *args, PyObject *kwds) - { - obj_data_t *self = (obj_data_t *)type->tp_alloc(type, 0); - return (PyObject *)self; - } - static PyObject *release(PyTypeObject *type, PyObject *args) - { - obj_data_t *self = (obj_data_t *)type; - self->release(); - return Py_BuildValue("i", 1); - } - static static_pytype_info_t pytype_info; -}; -template -static_pytype_info_t pyclass_base_info_t::pytype_info; - -//! 方便生成pyclass 初始化函数 -template -struct pyclass_ctor_tool_t; - -//! used to gen method of py class -template -struct pyclass_method_gen_t; - -//! 防止出现指针为NULL调用出错 -#define NULL_PTR_GUARD(X) if (NULL == X) {PyErr_SetString(PyExc_TypeError, "obj data ptr NULL");return NULL;} - -//! 用于生成python 的getter和setter接口,适配于c++ class的成员变量 -template -struct pyclass_member_func_gen_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - typedef RET CLASS_TYPE::* property_ptr_t; - - static PyObject *getter_func(obj_data_t *self, void *closure) - { - property_ptr_t property_ptr; - ::memcpy((void*)&property_ptr, (const void*)&closure, sizeof(closure)); - NULL_PTR_GUARD(self->obj); - CLASS_TYPE* p = self->obj; - return pytype_traits_t::pyobj_from_cppobj(p->*property_ptr); - } - static int setter_func(obj_data_t *self, PyObject *value, void *closure) - { - property_ptr_t property_ptr; - ::memcpy((void*)&property_ptr, (const void*)&closure, sizeof(closure)); - CLASS_TYPE* p = self->obj; - - return pytype_traits_t::pyobj_to_cppobj(value, p->*property_ptr); - } -}; - -//! 用于C++ 注册class的工具类,会记录class对应的名称、成员方法、成员变量 -class pyclass_regigster_tool_t -{ -public: - struct method_info_t - { - PyCFunction func; - string func_name; - string func_real_name; - string doc; - string doc_real; - int args_num; - int option_args_num; - long func_addr; - }; - struct property_info_t - { - void* ptr; - string property_name; - string doc; - getter getter_func; - setter setter_func; - }; - virtual ~pyclass_regigster_tool_t(){} - - typedef PyObject *(*pyobj_alloc_t)(PyTypeObject*, PyObject*, PyObject*); - - string class_name; - string class_real_name; - string class_name_with_mod; - string class_reel_name_with_mod; - string inherit_name; - int type_size; - string doc; - int args_num; - int option_args_num; - destructor dector; - initproc init; - pyobj_alloc_t ctor; - - //! member functions - PyCFunction delete_func; - vector methods_info; - //! property - vector propertys_info; - //! for init module - PyTypeObject pytype_def; - //! method - vector pymethod_def; - //! property - vector pyproperty_def; - - //! 静态类型需要全局记录该类型被注册成神马python 类型 - static_pytype_info_t* static_pytype_info; - - template - pyclass_regigster_tool_t& reg(FUNC f_, const string& func_name_, string doc_ = "") - { - method_info_t tmp; - tmp.func_name = func_name_; - tmp.func_real_name = func_name_ + "_internal_"; - tmp.doc = doc_; - tmp.doc_real = "internal use"; - tmp.func = (PyCFunction)pyclass_method_gen_t::pymethod; - tmp.args_num = pyclass_method_gen_t::args_num(); - tmp.option_args_num = pyclass_method_gen_t::option_args_num(); - ::memcpy((void*)&tmp.func_addr, (const void*)&f_, sizeof(void*)); - methods_info.push_back(tmp); - return *this; - } - template - pyclass_regigster_tool_t& reg_property(RET CLASS_TYPE::* member_, const string& member_name_, string doc_ = "") - { - property_info_t tmp; - ::memcpy((void*)&tmp.ptr, (const void*)&member_, sizeof(member_)); - tmp.property_name = member_name_; - tmp.doc = doc_; - tmp.getter_func = (getter)pyclass_member_func_gen_t::getter_func; - tmp.setter_func = (setter)pyclass_member_func_gen_t::setter_func; - propertys_info.push_back(tmp); - return *this; - } -}; - - -template -struct type_ref_traits_t -{ - typedef T value_t; - typedef T& ref_t; - value_t value; -}; -template -struct type_ref_traits_t -{ - typedef T value_t; - typedef T& ref_t; - value_t value; -}; -template -struct type_ref_traits_t -{ - typedef T value_t; - typedef T& ref_t; - value_t value; -}; -//! 用于判断是否是可选参数 -template -struct pyoption_traits_t -{ - static int is() { return 0;} -}; -template -struct pyoption_traits_t > -{ - static int is() { return 1;} -}; - - -template<>//typename T> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const long& val_) - { - return PyLong_FromLong(long(val_)); - } - static int pyobj_to_cppobj(PyObject *pvalue_, long& m_ret) - { - if (true == PyLong_Check(pvalue_)) - { - m_ret = (long)PyLong_AsLong(pvalue_); - return 0; - } - else if (true == PyInt_Check(pvalue_)) - { - m_ret = (long)PyInt_AsLong(pvalue_); - return 0; - } - return -1; - } - static const char* get_typename() { return "long";} -}; - -#define IMPL_INT_CODE(X) \ -template<> \ -struct pytype_traits_t \ -{ \ - static PyObject* pyobj_from_cppobj(const X& val_) \ - { \ - return PyInt_FromLong(long(val_)); \ - } \ - static int pyobj_to_cppobj(PyObject *pvalue_, X& m_ret) \ - { \ - if (true == PyLong_Check(pvalue_)) \ - { \ - m_ret = (X)PyLong_AsLong(pvalue_); \ - return 0; \ - } \ - else if (true == PyInt_Check(pvalue_)) \ - { \ - m_ret = (X)PyInt_AsLong(pvalue_); \ - return 0; \ - } \ - return -1; \ - } \ - static const char* get_typename() { return #X;} \ -}; - -IMPL_INT_CODE(int) -IMPL_INT_CODE(unsigned int) -IMPL_INT_CODE(short) -IMPL_INT_CODE(unsigned short) -IMPL_INT_CODE(char) -IMPL_INT_CODE(unsigned char) - -#ifdef _WIN32 -IMPL_INT_CODE(unsigned long) -#else -#ifndef __x86_64__ -IMPL_INT_CODE(int64_t) -#endif -IMPL_INT_CODE(uint64_t) -#endif - -template -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const T* val_) - { - const string& mod_name = pyclass_base_info_t::pytype_info.mod_name; - const string& class_name = pyclass_base_info_t::pytype_info.class_name; - PyObject *pName = NULL, *pModule = NULL, *pValue = NULL; - - if (class_name.empty()) - return pytype_traits_t::pyobj_from_cppobj(long(val_)); - - pName = PyString_FromString(mod_name.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - if (PyErr_Occurred()) - PyErr_Print(); - fprintf(stderr, "Failed to load \"%s\"\n", mod_name.c_str()); - assert(NULL && "this can not be happened"); - return NULL; - } - PyObject *pyclass = PyObject_GetAttrString(pModule, class_name.c_str()); - if (pyclass && PyCallable_Check(pyclass)) { - PyObject *pArgs = PyTuple_New(pyclass_base_info_t::pytype_info.total_args_num+1); - for (int i = 0; i< pyclass_base_info_t::pytype_info.total_args_num; ++i) - { - PyTuple_SetItem(pArgs, i, pytype_traits_t::pyobj_from_cppobj(0)); - } - - PyObject *palloc = pyclass_base_info_t::alloc_obj(pyclass_base_info_t::pytype_info.pytype_def, NULL, NULL); - typename pyclass_base_info_t::obj_data_t* pdest_obj = (typename pyclass_base_info_t::obj_data_t*)palloc; - //pdest_obj->obj = val_; - ::memcpy((void*)&pdest_obj->obj, (const void*)&val_, sizeof(pdest_obj->obj)); - pdest_obj->disable_auto_release(); - PyTuple_SetItem(pArgs, pyclass_base_info_t::pytype_info.total_args_num, palloc); - pValue = PyObject_CallObject(pyclass, pArgs); - Py_XDECREF(pArgs); - } - - Py_XDECREF(pyclass); - Py_DECREF(pModule); - return pValue; - } - - static int pyobj_to_cppobj(PyObject *pvalue_, T*& m_ret) - { - PyObject *pysrc = PyObject_GetAttrString(pvalue_, "obj"); - //!PyObject_TypeCheck(pysrc, pyclass_base_info_t::pytype_info.pytype_def)) { - if (NULL == pysrc || false == cpp_to_pyclass_reg_info_t::is_instance(pysrc, pyclass_base_info_t::pytype_info.class_name)) - { - Py_XDECREF(pysrc); - return -1; - } - typename pyclass_base_info_t::obj_data_t* pdest_obj = (typename pyclass_base_info_t::obj_data_t*)pysrc; - - m_ret = pdest_obj->obj; - Py_XDECREF(pysrc); - return 0; - } - - static const char* get_typename() { return pyclass_base_info_t::pytype_info.class_name.c_str();} -}; - -template -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(T* val_) - { - return pytype_traits_t::pyobj_from_cppobj(val_); - } - static int pyobj_to_cppobj(PyObject *pvalue_,T*& m_ret) - { - return pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret); - } - static const char* get_typename() { return pyclass_base_info_t::pytype_info.class_name.c_str();} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(PyObject* val_) - { - return val_; - } - static int pyobj_to_cppobj(PyObject *pvalue_, PyObject*& m_ret) - { - m_ret = pvalue_; - return 0; - } - static const char* get_typename() { return "PyObject";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const char* const val_) - { - return PyString_FromString(val_); - } - /* - static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) - { - if (true == PyString_Check(pvalue_)) - { - m_ret = PyString_AsString(pvalue_); - return 0; - } - return -1; - } - */ - static const char* get_typename() { return "string";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const char*& val_) - { - return PyString_FromString(val_); - } - /* - static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) - { - if (true == PyString_Check(pvalue_)) - { - m_ret = PyString_AsString(pvalue_); - return 0; - } - return -1; - } - */ - static const char* get_typename() { return "string";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(bool val_) - { - if (val_) - { - Py_RETURN_TRUE; - } - Py_RETURN_FALSE; - } - static int pyobj_to_cppobj(PyObject *pvalue_, bool& m_ret) - { - if (Py_False == pvalue_|| Py_None == pvalue_) - { - m_ret = false; - } - else - { - m_ret = true; - } - return 0; - } - static const char* get_typename() { return "bool";} -}; - -template -struct pytype_traits_t > -{ - static int pyobj_to_cppobj(PyObject *pvalue_, pyoption_t& m_ret) - { - if (Py_None == pvalue_) - { - return 0; - } - else if (0 == pytype_traits_t::value_t>::pyobj_to_cppobj(pvalue_, m_ret.value())) - { - m_ret.set(); - return 0; - } - return -1; - } - static const char* get_typename() { return "pyoption_t";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const string& val_) - { - return PyString_FromStringAndSize(val_.c_str(), val_.size()); - } - static int pyobj_to_cppobj(PyObject *pvalue_, string& m_ret) - { - if (true == PyString_Check(pvalue_)) - { - char* pDest = NULL; - Py_ssize_t nLen = 0; - PyString_AsStringAndSize(pvalue_, &pDest, &nLen); - - m_ret.assign(pDest, nLen); - return 0; - } - else if (true == PyUnicode_Check(pvalue_)) - { - char* pDest = NULL; - Py_ssize_t nLen = 0; - PyString_AsStringAndSize(pvalue_, &pDest, &nLen); - m_ret.assign(pDest, nLen); - return 0; - /* -#ifdef _WIN32 - PyObject* retStr = PyUnicode_AsEncodedString(pvalue_, "gbk", ""); -#else - PyObject* retStr = PyUnicode_AsUTF8String(pvalue_); -#endif - if (retStr) - { - m_ret = PyString_AsString(retStr); - Py_XDECREF(retStr); - return 0; - } - */ - } - return -1; - } - static const char* get_typename() { return "string";} -}; - -#ifdef _WIN32 -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const wstring& wstr) - { - return PyUnicode_FromWideChar(wstr.c_str(), wstr.length()); - } - static int pyobj_to_cppobj(PyObject *pvalue_, wstring& wstr_ret) - { - if (true == PyString_Check(pvalue_)) - { - PyObject* retStr = PyUnicode_FromObject(pvalue_); - if (retStr) - { - int n = PyUnicode_GetSize(retStr); - wstr_ret.resize(n); - n = PyUnicode_AsWideChar((PyUnicodeObject*)retStr, &(wstr_ret[0]), n); - Py_XDECREF(retStr); - return 0; - } - return 0; - } - else if (true == PyUnicode_Check(pvalue_)) - { - int n = PyUnicode_GetSize(pvalue_); - wstr_ret.resize(n); - n = PyUnicode_AsWideChar((PyUnicodeObject*)pvalue_, &(wstr_ret[0]), n); - return 0; - } - return -1; - } - static const char* get_typename() { return "wstring";} -}; -#endif - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(float val_) - { - return PyFloat_FromDouble(double(val_)); - } - static int pyobj_to_cppobj(PyObject *pvalue_, float& m_ret) - { - if (true == PyFloat_Check(pvalue_)) - { - m_ret = (float)PyFloat_AsDouble(pvalue_); - return 0; - } - return -1; - } - static const char* get_typename() { return "float";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(double val_) - { - return PyFloat_FromDouble(val_); - } - static int pyobj_to_cppobj(PyObject *pvalue_, double& m_ret) - { - if (true == PyFloat_Check(pvalue_)) - { - m_ret = PyFloat_AsDouble(pvalue_); - return 0; - } - return -1; - } - static const char* get_typename() { return "double";} -}; - -template -struct pytype_traits_t > -{ - static PyObject* pyobj_from_cppobj(const vector& val_) - { - PyObject* ret = PyList_New(val_.size()); - for (size_t i = 0; i < val_.size(); ++i) - { - PyList_SetItem(ret, i, pytype_traits_t::pyobj_from_cppobj(val_[i])); - } - return ret; - } - static int pyobj_to_cppobj(PyObject *pvalue_, vector& m_ret) - { - m_ret.clear(); - if (true == PyTuple_Check(pvalue_)) - { - int n = PyTuple_Size(pvalue_); - for (int i = 0; i < n; ++i) - { - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyTuple_GetItem(pvalue_, i))) - { - return -1; - } - m_ret.push_back(ret_tool.get_value()); - } - return 0; - } - else if (true == PyList_Check(pvalue_)) - { - int n = PyList_Size(pvalue_); - for (int i = 0; i < n; ++i) - { - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyList_GetItem(pvalue_, i))) - { - return -1; - } - m_ret.push_back(ret_tool.get_value()); - } - return 0; - } - return -1; - } - static const char* get_typename() { return "vector";} -}; -template -struct pytype_traits_t > -{ - static PyObject* pyobj_from_cppobj(const list& val_) - { - size_t n = val_.size(); - PyObject* ret = PyList_New(n); - int i = 0; - for (typename list::const_iterator it = val_.begin(); it != val_.end(); ++it) - { - PyList_SetItem(ret, i++, pytype_traits_t::pyobj_from_cppobj(*it)); - } - return ret; - } - static int pyobj_to_cppobj(PyObject *pvalue_, list& m_ret) - { - pytype_tool_impl_t ret_tool; - if (true == PyTuple_Check(pvalue_)) - { - int n = PyTuple_Size(pvalue_); - for (int i = 0; i < n; ++i) - { - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyTuple_GetItem(pvalue_, i))) - { - return -1; - } - m_ret.push_back(ret_tool.get_value()); - } - return 0; - } - else if (true == PyList_Check(pvalue_)) - { - int n = PyList_Size(pvalue_); - for (int i = 0; i < n; ++i) - { - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyList_GetItem(pvalue_, i))) - { - return -1; - } - m_ret.push_back(ret_tool.get_value()); - } - return 0; - } - return -1; - } - static const char* get_typename() { return "list";} -}; -template -struct pytype_traits_t > -{ - static PyObject* pyobj_from_cppobj(const set& val_) - { - PyObject* ret = PySet_New(NULL); - for (typename set::const_iterator it = val_.begin(); it != val_.end(); ++it) - { - PyObject *v = pytype_traits_t::pyobj_from_cppobj(*it); - PySet_Add(ret, v); - Py_DECREF(v); - } - return ret; - } - static int pyobj_to_cppobj(PyObject *pvalue_, set& m_ret) - { - m_ret.clear(); - pytype_tool_impl_t ret_tool; - PyObject *iter = PyObject_GetIter(pvalue_); - PyObject *item = NULL; - while (NULL != iter && NULL != (item = PyIter_Next(iter))) - { - T tmp(); - if (pytype_traits_t::pyobj_to_cppobj(item, tmp)) - { - Py_DECREF(item); - Py_DECREF(iter); - return -1; - } - m_ret.insert(tmp); - Py_DECREF(item); - } - if (iter) - { - Py_DECREF(iter); - return 0; - } - return -1; - } - static const char* get_typename() { return "set";} -}; -template -struct pytype_traits_t > -{ - static PyObject* pyobj_from_cppobj(const map& val_) - { - PyObject* ret = PyDict_New(); - for (typename map::const_iterator it = val_.begin(); it != val_.end(); ++it) - { - PyObject *k = pytype_traits_t::pyobj_from_cppobj(it->first); - PyObject *v = pytype_traits_t::pyobj_from_cppobj(it->second); - PyDict_SetItem(ret, k, v); - Py_DECREF(k); - Py_DECREF(v); - } - return ret; - } - static int pyobj_to_cppobj(PyObject *pvalue_, map& m_ret) - { - m_ret.clear(); - pytype_tool_impl_t ret_tool_T; - pytype_tool_impl_t ret_tool_R; - if (true == PyDict_Check(pvalue_)) - { - PyObject *key = NULL, *value = NULL; - Py_ssize_t pos = 0; - - while (PyDict_Next(pvalue_, &pos, &key, &value)) - { - T tmp_key; - R tmp_value; - if (pytype_traits_t::pyobj_to_cppobj(key, tmp_key) || - pytype_traits_t::pyobj_to_cppobj(value, tmp_value)) - { - return -1; - } - m_ret[tmp_key] = tmp_value; - } - return 0; - } - return -1; - } - static const char* get_typename() { return "map";} -}; - -//! ��ȡpython�����ķ���ֵ,������ -template -class pytype_tool_impl_t: public pytype_tool_t -{ -public: - pytype_tool_impl_t():m_ret(){} - - virtual int parse_value(PyObject *pvalue_) - { - if (pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret)) - { - return -1; - } - return 0; - } - - const T& get_value() const { return m_ret; } - virtual const char* return_type() {return pytype_traits_t::get_typename();} -private: - T m_ret; -}; - -template<> -class pytype_tool_impl_t: public pytype_tool_t -{ -public: - pytype_tool_impl_t():m_ret(){} - - virtual int parse_value(PyObject *pvalue_) - { - return 0; - } - - const cpp_void_t& get_value() const { return m_ret; } - virtual const char* return_type() { return "void";} -private: - cpp_void_t m_ret; -}; -template -class pytype_tool_impl_t: public pytype_tool_t -{ -public: - pytype_tool_impl_t():m_ret(){} - - virtual int parse_value(PyObject *pvalue_) - { - if (pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret)) - { - return -1; - } - return 0; - } - - T* get_value() const { return m_ret; } -private: - T* m_ret; -}; - - -template<> -class pytype_tool_impl_t: public pytype_tool_t -{ -public: - pytype_tool_impl_t():m_ret(){} - - virtual int parse_value(PyObject *pvalue_) - { - m_ret = pvalue_; - return 0; - } - - PyObject*& get_value() { return m_ret; } - bool need_release() { return false; } -private: - PyObject* m_ret; -}; - -#endif diff --git a/VersionForRead/pyops_for_embed.h b/VersionForRead/pyops_for_embed.h deleted file mode 100644 index e91a7f3..0000000 --- a/VersionForRead/pyops_for_embed.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef __PYOPS_FOR_EMBED -#define __PYOPS_FOR_EMBED - -#include "pyops_base.h" - - - - - -template -const T& pycall_t::call(const string& mod_name_, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) -{ - PyObject *pName = NULL, *pModule = NULL; - string err_msg; - - pName = PyString_FromString(mod_name_.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - return pyret.get_value(); - } - - call_func(pModule, mod_name_, func_name_, pyarg_, pyret, err_msg); - Py_DECREF(pModule); - - if (!err_msg.empty()) - { - throw runtime_error(err_msg.c_str()); - } - return pyret.get_value(); -} -template -const T& pycall_t::call_obj_method(PyObject *pObj, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) -{ - string err_msg; - if (NULL == pObj) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - return pyret.get_value(); - } - - static string mod_name_ = "NaN"; - call_func(pObj, mod_name_, func_name_, pyarg_, pyret, err_msg); - - if (!err_msg.empty()) - { - throw runtime_error(err_msg.c_str()); - } - return pyret.get_value(); -} - -template -const T& pycall_t::call_lambda(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) -{ - string err_msg; - if (NULL == pFunc) - { - err_msg = "can not call null PyObject"; - throw runtime_error(err_msg.c_str()); - return pyret.get_value(); - } - - call_func_obj(pFunc, pyarg_, pyret, err_msg); - - if (!err_msg.empty()) - { - throw runtime_error(err_msg.c_str()); - } - return pyret.get_value(); -} - - -#endif diff --git a/VersionForRead/pyops_for_extend.h b/VersionForRead/pyops_for_extend.h deleted file mode 100644 index e91ca90..0000000 --- a/VersionForRead/pyops_for_extend.h +++ /dev/null @@ -1,1745 +0,0 @@ -#ifndef __PYOPS_FOR_EXTEND_ -#define __PYOPS_FOR_EXTEND_ - -#include "pyops_base.h" - - - -//! 用于扩展python的工具类,用来解析参数 -struct pyext_tool_t -{ - pyext_tool_t(PyObject* args_): - m_args(args_), - m_arg_tuple(NULL), - m_index(0), - m_err(false), - m_func_addr(0) - { - if (!PyArg_ParseTuple(args_, "lO", &m_func_addr, &m_arg_tuple)) { - m_err = true; - return; - } - if (NULL == m_arg_tuple || false == PyTuple_Check(m_arg_tuple)) - { - PyErr_SetString(PyExc_TypeError, "arg type invalid(shoule func_name, args tuple)"); - m_err = true; - return; - } - m_size = PyTuple_Size(m_arg_tuple); - } - - template - pyext_tool_t& parse_arg(T& ret_arg_) - { - typedef typename type_ref_traits_t::value_t value_t; - if (false == m_err) - { - if (m_index >= m_size) - { - stringstream ss; - ss << "param num invalid, only["<< m_index + 1 <<"] provided"; - PyErr_SetString(PyExc_TypeError, ss.str().c_str()); - m_err = true; - return *this; - } - - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyTuple_GetItem(m_arg_tuple, m_index))) - { - stringstream ss; - ss << "param[" << m_index + 1 << "] type invalid, "<< pytype_traits_t::get_typename() << " needed"; - PyErr_SetString(PyExc_TypeError, ss.str().c_str()); - m_err = true; - return *this; - } - ++m_index; - ret_arg_ = ret_tool.get_value(); - } - return *this; - } - - bool is_err() const { return m_err;} - long get_func_addr() const { return m_func_addr;} - - template - FUNC get_func_ptr() const - { - FUNC f = NULL; - ::memcpy((void*)&f, (const void*)&m_func_addr, sizeof(m_func_addr)); - return f; - } - PyObject* m_args; - PyObject* m_arg_tuple; - int m_index; - int m_size; - bool m_err;//! 是否异常 - long m_func_addr; -}; - - - -//! 用于扩展python,生成pyobject类型的返回值给python -template -struct pyext_return_tool_t -{ - //! 用于静态方法 - template - static PyObject* route_call(F f) - { - return pytype_traits_t::pyobj_from_cppobj(f()); - } - template - static PyObject* route_call(F f, ARG1& a1) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value, a8.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value, a8.value, a9.value)); - } - //! 用于成员方法 - template - static PyObject* route_method_call(O o, F f) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)()); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value, a8.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value, a8.value, a9.value)); - } -}; - - -template<> -struct pyext_return_tool_t -{ - template - static PyObject* route_call(F f) - { - f(); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1) - { - f(a1.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2) - { - f(a1.value, a2.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3) - { - f(a1.value, a2.value, a3.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) - { - f(a1.value, a2.value, a3.value, a4.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f) - { - (o->*f)(); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1) - { - (o->*f)(a1.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2) - { - (o->*f)(a1.value, a2.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3) - { - (o->*f)(a1.value, a2.value, a3.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); - Py_RETURN_NONE; - } -}; - - - -//! 用于扩展python,traits出注册给python的函数接口 -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(); - static int args_num() { return 0;} - static int option_args_num() { return 0;} - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - return pyext_return_tool_t::route_call(f); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1); - static int args_num(){ return 1-option_args_num();} - static int option_args_num() - { - return pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - if (pyext_tool.parse_arg(a1.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2); - static int args_num() { return 2 - option_args_num();} - static int option_args_num() - { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3); - static int args_num() { return 3-option_args_num();} - static int option_args_num() - { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3); - } -}; -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4); - static int args_num() { return 4-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5); - static int args_num() { return 5-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); - static int args_num() { return 6-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); - static int args_num() { return 7-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); - static int args_num() { return 8-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7, a8); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); - static int args_num() { return 9-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - type_ref_traits_t a9; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7, a8, a9); - } -}; - -//! ��������pyclass ��ʼ������ -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - - self->obj = new CLASS_TYPE(); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - if (pyext_tool.parse_arg(a1.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - type_ref_traits_t a9; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); - return 0; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(); - static int args_num() { return 0;} - static int option_args_num() { return 0;} - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1); - static int args_num() { return 1-option_args_num();} - static int option_args_num() { return pyoption_traits_t::value_t>::is();} - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - if (pyext_tool.parse_arg(a1.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2); - static int args_num() { return 2-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2);; - } -}; - - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3); - static int args_num() { return 3-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4); - static int args_num() { return 4-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5); - static int args_num() { return 5-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); - static int args_num() { return 6-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); - static int args_num() { return 7-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); - static int args_num() { return 8-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8);; - } -}; - - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); - static int args_num() { return 9-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - type_ref_traits_t a9; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8, a9);; - } -}; - -//! const类型成员函数--------------------------------------------------------------------------------------------- - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)() const; - static int args_num() { return 0;} - static int option_args_num() { return 0;} - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1) const; - static int args_num() { return 1-option_args_num();} - static int option_args_num() { return pyoption_traits_t::value_t>::is();} - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - if (pyext_tool.parse_arg(a1.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2) const; - static int args_num() { return 2-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2);; - } -}; - - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3) const; - static int args_num() { return 3-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4) const; - static int args_num() { return 4-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5) const; - static int args_num() { return 5-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) const; - static int args_num() { return 6-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) const; - static int args_num() { return 7-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8) const; - static int args_num() { return 8-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8);; - } -}; - - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9) const; - static int args_num() { return 9-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - type_ref_traits_t a9; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8, a9);; - } -}; - - -#endif diff --git a/example.cpp b/example.cpp index f1d63f9..4ae00e2 100644 --- a/example.cpp +++ b/example.cpp @@ -10,113 +10,111 @@ void test_base(ffpython_t& ffpython) { - printf("sys.version=%s\n", ffpython.get_global_var("sys", "version").c_str()); + printf("sys.version=%s\n", ffpython.get_global_var("sys", "version").c_str()); ffpython.set_global_var("fftest", "global_var", "OhNice"); - printf("fftest.global_var=%s\n", ffpython.get_global_var("fftest", "global_var").c_str()); - printf("time.asctime=%s\n", ffpython.call("time", "asctime").c_str()); - int a1 = 100; float a2 = 3.14f; string a3 = "OhWell"; + printf("fftest.global_var=%s\n", ffpython.get_global_var("fftest", "global_var").c_str()); + printf("os.getcwd=%s\n", ffpython.call("os", "getcwd").c_str()); + printf("time.asctime=%s\n", ffpython.call("time", "asctime").c_str()); + int a1 = 100; float a2 = 3.14f; std::string a3 = "OhWell"; ffpython.call("fftest", "test_base", a1, a2, a3); } void test_stl(ffpython_t& ffpython) { - vector a1;a1.push_back(100);a1.push_back(200); - list a2; a2.push_back("Oh");a2.push_back("Nice"); - vector > a3;a3.push_back(a2); + std::vector a1;a1.push_back(100);a1.push_back(200); + std::list a2; a2.push_back("Oh");a2.push_back("Nice"); + std::vector > a3;a3.push_back(a2); ffpython.call("fftest", "test_stl", a1, a2, a3); } void test_return_stl(ffpython_t& ffpython) { - typedef map > > ret_t; + typedef std::map > > ret_t; ret_t val = ffpython.call("fftest", "test_return_stl"); } -static int print_val(int a1, int a2, const string& a3, const vector& a4) +static int print_val(int a1, float a2, const std::string& a3, const std::vector& a4) { - //printf("%s[%d,%f,%s,%d]\n", __FUNCTION__, a1, a2, a3.c_str(), a4.size()); + printf("%s[%d,%g,%s,%d]\n", __FUNCTION__, a1, a2, a3.c_str(), (int)a4.size()); return 0; } struct ops_t { - static list return_stl() + static std::list return_stl() { - list ret;ret.push_back(1024); + std::list ret;ret.push_back(1024); printf("%s\n", __FUNCTION__); return ret; } }; - -void test_reg_function() +void test_register_base_class(ffpython_t& ffpython) { - ffpython_t ffpython;//("ext1"); - ffpython.reg(&print_val, "print_val") - .reg(&ops_t::return_stl, "return_stl"); - ffpython.init("ext1"); - ffpython.call("fftest", "test_reg_function"); -} + ffpython.call("fftest", "test_register_base_class"); +}; class foo_t { public: - foo_t(int v_):m_value(v_) + foo_t(int v_) :m_value(v_) + { + printf("%s\n", __FUNCTION__); + } + virtual ~foo_t() { printf("%s\n", __FUNCTION__); } - virtual ~foo_t() - { - printf("%s\n", __FUNCTION__); - } int get_value() const { return m_value; } void set_value(int v_) { m_value = v_; } - void test_stl(map >& v_) + void test_stl(std::map >& v_) { printf("%s\n", __FUNCTION__); } int m_value; }; -class dumy_t: public foo_t +class dumy_t : public foo_t { public: - dumy_t(int v_):foo_t(v_) - { - printf("%s\n", __FUNCTION__); - } - ~dumy_t() - { - printf("%s\n", __FUNCTION__); - } - void dump() - { - printf("%s\n", __FUNCTION__); - } + dumy_t(int v_) :foo_t(v_) + { + printf("%s\n", __FUNCTION__); + } + ~dumy_t() + { + printf("%s\n", __FUNCTION__); + } + void dump() + { + printf("%s\n", __FUNCTION__); + } }; static foo_t* obj_test(dumy_t* p) { - printf("%s\n", __FUNCTION__); - return p; + printf("%s\n", __FUNCTION__); + return p; } -void test_register_base_class(ffpython_t& ffpython) +std::string test_reg_function(ffpython_t& ffpython) { + ffpython.reg(&print_val, "print_val") + .reg(&ops_t::return_stl, "return_stl"); + ffpython.reg_class("foo_t") - .reg(&foo_t::get_value, "get_value") - .reg(&foo_t::set_value, "set_value") - .reg(&foo_t::test_stl, "test_stl") - .reg_property(&foo_t::m_value, "m_value"); + .reg(&foo_t::get_value, "get_value") + .reg(&foo_t::set_value, "set_value") + .reg(&foo_t::test_stl, "test_stl") + .reg_property(&foo_t::m_value, "m_value"); - ffpython.reg_class("dumy_t", "dumy_t class inherit foo_t ctor ", "foo_t") - .reg(&dumy_t::dump, "dump"); + ffpython.reg_class("dumy_t", "dumy_t class inherit foo_t ctor ", "foo_t") + .reg(&dumy_t::dump, "dump"); - ffpython.reg(obj_test, "obj_test"); + ffpython.reg(obj_test, "obj_test"); + return "cppext"; +} - ffpython.init("ext2"); - ffpython.call("fftest", "test_register_base_class"); -}; void test_register_inherit_class(ffpython_t& ffpython) { @@ -126,7 +124,7 @@ void test_register_inherit_class(ffpython_t& ffpython) void test_cpp_obj_to_py(ffpython_t& ffpython) { foo_t tmp_foo(2013); - vector vt; + std::vector vt; vt.push_back(&tmp_foo); ffpython.call("fftest", "test_cpp_obj_to_py", &tmp_foo); printf("test_cpp_obj_to_py changed m_value=%d\n", tmp_foo.m_value); @@ -144,7 +142,7 @@ void test_cpp_obj_py_obj(ffpython_t& ffpython) void test_py_class_lambda(ffpython_t& ffpython) { PyObject* pobj = ffpython.call("fftest", "test_cpp_obj_return_py_obj"); - ffpython.obj_call(pobj, "sayHi", 1, string("soNice")); + ffpython.obj_call(pobj, "sayHi", 1, std::string("soNice")); PyObject* pFunc= ffpython.call("fftest", "test_cpp_obj_return_py_lambda"); ffpython.call_lambda(pFunc, 112233); @@ -155,26 +153,35 @@ void test_py_class_lambda(ffpython_t& ffpython) int main(int argc, char* argv[]) { - Py_Initialize(); + try { - ffpython_t::add_path("./"); - ffpython_t ffpython;//("ext2"); + ffpython_t ffpython(&test_reg_function); + ffpython_t::add_path("./"); + ffpython_t::add_path("../"); - TestGuard("test_base", test_base(ffpython)); - TestGuard("test_stl", test_stl(ffpython)); - TestGuard("test_reg_function", test_reg_function()); - TestGuard("test_register_base_class", test_register_base_class(ffpython)); + TestGuard("test_base", test_base(ffpython)); + + TestGuard("test_stl", test_stl(ffpython)); + ffpython.call("fftest", "test_reg_function"); + + TestGuard("test_register_base_class", test_register_base_class(ffpython)); + + TestGuard("test_register_inherit_class", test_register_inherit_class(ffpython)); + + TestGuard("test_cpp_obj_to_py", test_cpp_obj_to_py(ffpython));return 0; + + TestGuard("test_cpp_obj_py_obj", test_cpp_obj_py_obj(ffpython)); + + TestGuard("test_py_class_lambda", test_py_class_lambda(ffpython)); - TestGuard("test_register_inherit_class", test_register_inherit_class(ffpython)); - TestGuard("test_cpp_obj_to_py", test_cpp_obj_to_py(ffpython)); - TestGuard("test_cpp_obj_py_obj", test_cpp_obj_py_obj(ffpython)); - - TestGuard("test_py_class_lambda", test_py_class_lambda(ffpython)); - #ifdef _WIN32 - system("pause"); + system("pause"); #endif - Py_Finalize(); + Py_Finalize(); + } + catch(std::exception& e) { + printf("exception<%s>\n", e.what()); + } printf("main exit...\n"); return 0; } diff --git a/ffpython.h b/ffpython.h index bfbf8d7..012a79c 100644 --- a/ffpython.h +++ b/ffpython.h @@ -1,665 +1,58 @@ #ifndef __FFPYTHON_H_ #define __FFPYTHON_H_ -#include +#ifdef _DEBUG +#undef _DEBUG +#include +#define _DEBUG +#else +#include +#endif #include #include -#include -#include -#include -#include -#include -#include using namespace std; -#ifdef _WIN32 -#define SAFE_SPRINTF _snprintf_s -#else -#define SAFE_SPRINTF snprintf -#endif - - -//! 获取python异常信息 -struct pyops_t -{ - static int traceback(string& ret_) - { - PyObject* err = PyErr_Occurred(); - - if (err != NULL) { - PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL; - PyObject *pyth_module = NULL, *pyth_func = NULL; - - PyErr_Fetch(&ptype, &pvalue, &ptraceback); - if (pvalue) - { - if (true == PyList_Check(pvalue)) - { - int n = PyList_Size(pvalue); - for (int i = 0; i < n; ++i) - { - PyObject *pystr = PyObject_Str(PyList_GetItem(pvalue, i)); - ret_ += PyString_AsString(pystr); - ret_ += "\n"; - Py_DECREF(pystr); - } - } - if (true == PyTuple_Check(pvalue)) - { - int n = PyTuple_Size(pvalue); - for (int i = 0; i < n; ++i) - { - PyObject* tmp_str = PyTuple_GetItem(pvalue, i); - if (true == PyTuple_Check(tmp_str)) - { - int m = PyTuple_Size(tmp_str); - for (int j = 0; j < m; ++j) - { - PyObject *pystr = PyObject_Str(PyTuple_GetItem(tmp_str, j)); - ret_ += PyString_AsString(pystr); - ret_ += ","; - Py_DECREF(pystr); - } - } - else - { - PyObject *pystr = PyObject_Str(tmp_str); - ret_ += PyString_AsString(pystr); - Py_DECREF(pystr); - } - ret_ += "\n"; - } - } - else - { - PyObject *pystr = PyObject_Str(pvalue); - if (pystr) - { - ret_ += PyString_AsString(pystr); - ret_ += "\n"; - Py_DECREF(pystr); - } - } - } - - /* See if we can get a full traceback */ - PyObject *module_name = PyString_FromString("traceback"); - pyth_module = PyImport_Import(module_name); - Py_DECREF(module_name); - - if (pyth_module && ptype && pvalue && ptraceback) - { - pyth_func = PyObject_GetAttrString(pyth_module, "format_exception"); - if (pyth_func && PyCallable_Check(pyth_func)) { - PyObject *pyth_val = PyObject_CallFunctionObjArgs(pyth_func, ptype, pvalue, ptraceback, NULL); - if (pyth_val && true == PyList_Check(pyth_val)) - { - int n = PyList_Size(pyth_val); - for (int i = 0; i < n; ++i) - { - PyObject* tmp_str = PyList_GetItem(pyth_val, i); - PyObject *pystr = PyObject_Str(tmp_str); - if (pystr) - { - ret_ += PyString_AsString(pystr); - - Py_DECREF(pystr); - } - ret_ += "\n"; - } - } - Py_XDECREF(pyth_val); - } - } - Py_XDECREF(pyth_func); - Py_XDECREF(pyth_module); - Py_XDECREF(ptype); - Py_XDECREF(pvalue); - Py_XDECREF(ptraceback); - PyErr_Clear(); - return 0; - } - - return -1; - } -}; -struct cpp_void_t{}; - -//! 用于抽取类型、类型对应的引用 -template -struct type_ref_traits_t; - -//! 用于python 可选参数 -template -struct pyoption_t -{ - typedef typename type_ref_traits_t::value_t value_t; - pyoption_t():m_set_flag(false){} - bool is_set() const { return m_set_flag;} - void set() { m_set_flag = true;} - value_t& value() { return m_value;} - const value_t& value() const{ return m_value;} - - const value_t& value(const value_t& default_) - { - if (is_set()) - return m_value; - else - return default_; - } - bool m_set_flag; - value_t m_value; -}; -//! 用于判断是否是可选参数 -template -struct pyoption_traits_t; - -//! pytype_traits_t 封装 PyLong_FromLong 相关的操作,用于为调用python生成参数 -template -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const char* const val_) - { - return PyString_FromString(val_); - } - /* - static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) - { - if (true == PyString_Check(pvalue_)) - { - m_ret = PyString_AsString(pvalue_); - return 0; - } - return -1; - } - */ - static const char* get_typename() { return "string";} -}; - -//! 用于调用python函数,生成tuple类型的python函数参数的工具类 -struct pycall_arg_t -{ - pycall_arg_t(int arg_num): - arg_index(0), - pargs_tuple(PyTuple_New(arg_num)) - {} - ~pycall_arg_t() - { - release(); - } - PyObject * get_args() const - { - return pargs_tuple; - } - template - pycall_arg_t& add(const T& val_) - { - if (arg_index < PyTuple_Size(pargs_tuple)) - { - PyObject* tmp_arg = pytype_traits_t::pyobj_from_cppobj(val_); - PyTuple_SetItem(pargs_tuple, arg_index, tmp_arg); - ++arg_index; - } - return *this; - } - void release() - { - if (pargs_tuple) - { - Py_DECREF(pargs_tuple); - pargs_tuple = NULL; - } - } - int arg_index; - PyObject * pargs_tuple; -}; - -//! 用于调用python函数,获取返回值的工具类 -class pytype_tool_t -{ -public: - virtual ~pytype_tool_t(){}; - virtual int parse_value(PyObject *pvalue_) = 0; - virtual const char* return_type() {return "";} - virtual bool need_release() { return true; } -}; - -//! 用于调用python函数,获取返回值的工具泛型类 -template -class pytype_tool_impl_t; -//! 封装调用python函数的C API -struct pycall_t -{ - static int call_func(PyObject *pModule, const string& mod_name_, const string& func_name_, - pycall_arg_t& pyarg_, pytype_tool_t& pyret_, string& err_) - { - PyObject *pFunc = PyObject_GetAttrString(pModule, func_name_.c_str()); - if (pFunc && PyCallable_Check(pFunc)) { - PyObject *pArgs = pyarg_.get_args(); - PyObject *pValue = PyObject_CallObject(pFunc, pArgs); - pyarg_.release();//! 等价于Py_DECREF(pArgs); - - if (pValue != NULL) { - if (pyret_.parse_value(pValue)) - { - err_ += "value returned is not "; - err_ += pyret_.return_type(); - err_ += string(" ") + func_name_ + " in " + mod_name_; - } - if (pyret_.need_release()){ - Py_DECREF(pValue); - } - } - } - else - { - err_ += "Cannot find function "; - err_ += func_name_ + " in " + mod_name_ + ","; - } - - Py_XDECREF(pFunc); - if (PyErr_Occurred()) - { - pyops_t::traceback(err_); - return 0; - } - return 0; - } - static int call_func_obj(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_t& pyret_, string& err_) - { - if (pFunc && PyCallable_Check(pFunc)) { - PyObject *pArgs = pyarg_.get_args(); - PyObject *pValue = PyObject_CallObject(pFunc, pArgs); - pyarg_.release();//! 等价于Py_DECREF(pArgs); - - if (pValue != NULL) { - if (pyret_.parse_value(pValue)) - { - err_ += "value returned is not "; - err_ += pyret_.return_type(); - } - if (pyret_.need_release()){ - Py_DECREF(pValue); - } - } - } - else - { - err_ += "invalid function"; - } - - if (PyErr_Occurred()) - { - pyops_t::traceback(err_); - return 0; - } - return 0; - } - template - static const T& call(const string& mod_name_, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); - template - static const T& call_obj_method(PyObject *pObj, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); - template - static const T& call_lambda(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); -}; -//! 用于扩展python的工具类,用来解析参数 -struct pyext_tool_t; - - -template -struct pyext_return_tool_t; - -//! 用于扩展python,生成pyobject类型的返回值给python -template -struct pyext_func_traits_t; - -//! 用于扩展python,traits出注册给python的函数接口 -#ifndef PYCTOR -#define PYCTOR int (*) -#endif -//! 表示void类型,由于void类型不能return,用void_ignore_t适配 -template -struct void_ignore_t; - -template -struct void_ignore_t -{ - typedef T value_t; -}; - -template<> -struct void_ignore_t -{ - typedef cpp_void_t value_t; -}; - -#define RET_V typename void_ignore_t::value_t - -//! 记录各个基类和子类的相互关系 -struct cpp_to_pyclass_reg_info_t -{ - struct inherit_info_t - { - inherit_info_t():pytype_def(NULL){} - PyTypeObject* pytype_def; - string inherit_name; - set all_child; - }; - typedef map inherit_info_map_t; - static inherit_info_map_t& get_all_info() - { - static inherit_info_map_t inherit_info; - return inherit_info; - } - - static void add(const string& child_, const string& base_, PyTypeObject* def_) - { - inherit_info_t tmp; - tmp.inherit_name = base_; - tmp.pytype_def = def_; - get_all_info()[child_] = tmp; - get_all_info()[base_].all_child.insert(def_); - } - static bool is_instance(PyObject* pysrc, const string& class_) - { - inherit_info_map_t& inherit_info = get_all_info(); - inherit_info_t& tmp = inherit_info[class_]; - if (tmp.pytype_def && PyObject_TypeCheck(pysrc, tmp.pytype_def)) - { - return true; - } - for (set::iterator it = tmp.all_child.begin(); it != tmp.all_child.end(); ++it) - { - if (*it && PyObject_TypeCheck(pysrc, *it)) - { - return true; - } - } - - return false; - } - -}; - - -//! 记录C++ class 对应到python中的名称、参数信息等,全局 -struct static_pytype_info_t -{ - string class_name; - string mod_name; - int total_args_num; - PyTypeObject* pytype_def; -}; - -//! 工具类,用于生成分配python class的接口,包括分配、释放 -template -struct pyclass_base_info_t -{ - struct obj_data_t - { - obj_data_t():obj(NULL){} - - PyObject_HEAD; - T* obj; - bool forbid_release; - void disable_auto_release(){ forbid_release = true; } - void release() - { - if (obj) - { - delete obj; - obj = NULL; - } - } - }; - - static void free_obj(obj_data_t* self) - { - if (false == self->forbid_release && self->obj) - { - self->release(); - } - self->ob_type->tp_free((PyObject*)self); - } - - static PyObject *alloc_obj(PyTypeObject *type, PyObject *args, PyObject *kwds) - { - obj_data_t *self = (obj_data_t *)type->tp_alloc(type, 0); - return (PyObject *)self; - } - static PyObject *release(PyTypeObject *type, PyObject *args) - { - obj_data_t *self = (obj_data_t *)type; - self->release(); - return Py_BuildValue("i", 1); - } - static static_pytype_info_t pytype_info; -}; -template -static_pytype_info_t pyclass_base_info_t::pytype_info; - -//! 方便生成pyclass 初始化函数 -template -struct pyclass_ctor_tool_t; - -//! used to gen method of py class -template -struct pyclass_method_gen_t; - -//! 防止出现指针为NULL调用出错 -#define NULL_PTR_GUARD(X) if (NULL == X) {PyErr_SetString(PyExc_TypeError, "obj data ptr NULL");return NULL;} +#include "pyops_base.h" +#include "pyops_for_embed.h" +#include "pyops_for_extend.h" -//! 用于生成python 的getter和setter接口,适配于c++ class的成员变量 -template -struct pyclass_member_func_gen_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - typedef RET CLASS_TYPE::* property_ptr_t; - - static PyObject *getter_func(obj_data_t *self, void *closure) - { - property_ptr_t property_ptr; - ::memcpy((void*)&property_ptr, (const void*)&closure, sizeof(closure)); - NULL_PTR_GUARD(self->obj); - CLASS_TYPE* p = self->obj; - return pytype_traits_t::pyobj_from_cppobj(p->*property_ptr); - } - static int setter_func(obj_data_t *self, PyObject *value, void *closure) - { - property_ptr_t property_ptr; - ::memcpy((void*)&property_ptr, (const void*)&closure, sizeof(closure)); - CLASS_TYPE* p = self->obj; - - return pytype_traits_t::pyobj_to_cppobj(value, p->*property_ptr); - } -}; - -//! 用于C++ 注册class的工具类,会记录class对应的名称、成员方法、成员变量 -class pyclass_regigster_tool_t +class ffpython_t { public: - struct method_info_t - { - PyCFunction func; - string func_name; - string func_real_name; - string doc; - string doc_real; - int args_num; - int option_args_num; - long func_addr; - }; - struct property_info_t - { - void* ptr; - string property_name; - string doc; - getter getter_func; - setter setter_func; - }; - virtual ~pyclass_regigster_tool_t(){} - - typedef PyObject *(*pyobj_alloc_t)(PyTypeObject*, PyObject*, PyObject*); - - string class_name; - string class_real_name; - string class_name_with_mod; - string class_reel_name_with_mod; - string inherit_name; - int type_size; - string doc; - int args_num; - int option_args_num; - destructor dector; - initproc init; - pyobj_alloc_t ctor; - - //! member functions - PyCFunction delete_func; - vector methods_info; - //! property - vector propertys_info; - //! for init module - PyTypeObject pytype_def; - //! method - vector pymethod_def; - //! property - vector pyproperty_def; - - //! 静态类型需要全局记录该类型被注册成神马python 类型 - static_pytype_info_t* static_pytype_info; - - template - pyclass_regigster_tool_t& reg(FUNC f_, const string& func_name_, string doc_ = "") - { - method_info_t tmp; - tmp.func_name = func_name_; - tmp.func_real_name = func_name_ + "_internal_"; - tmp.doc = doc_; - tmp.doc_real = "internal use"; - tmp.func = (PyCFunction)pyclass_method_gen_t::pymethod; - tmp.args_num = pyclass_method_gen_t::args_num(); - tmp.option_args_num = pyclass_method_gen_t::option_args_num(); - - ::memcpy((void*)&tmp.func_addr, (const void*)&f_, sizeof(void*)); - methods_info.push_back(tmp); - return *this; - } - template - pyclass_regigster_tool_t& reg_property(RET CLASS_TYPE::* member_, const string& member_name_, string doc_ = "") - { - property_info_t tmp; - ::memcpy((void*)&tmp.ptr, (const void*)&member_, sizeof(member_)); - tmp.property_name = member_name_; - tmp.doc = doc_; - tmp.getter_func = (getter)pyclass_member_func_gen_t::getter_func; - tmp.setter_func = (setter)pyclass_member_func_gen_t::setter_func; - propertys_info.push_back(tmp); - return *this; - } -}; + typedef std::string (*ModInitFunc)(ffpython_t&); - -class ffpython_t -{ struct reg_info_t { reg_info_t():args_num(0),option_args_num(0),func_addr(0){} int args_num; int option_args_num; - long func_addr; + PTR_NUMBER func_addr; PyCFunction func; - string func_name; - string func_impl_name; - string doc; - string doc_impl; + std::string func_name; + std::string func_impl_name; + std::string doc; + std::string doc_impl; }; public: - ffpython_t() - { - if (!Py_IsInitialized()) - Py_Initialize(); - } - ~ffpython_t() - { - clear_cache_pyobject(); - } - - static int init_py() - { - Py_Initialize(); - return 0; - } - static int final_py() - { - Py_Finalize(); - return 0; - } - - static int add_path(const string& path_) - { - char buff[1024]; - SAFE_SPRINTF(buff, sizeof(buff), "import sys\nif '%s' not in sys.path:\n\tsys.path.append('%s')\n", path_.c_str(), path_.c_str()); - PyRun_SimpleString(buff); - return 0; - } + ffpython_t(ModInitFunc func = NULL); + ~ffpython_t(); - static int run_string(const string& py_) - { - PyRun_SimpleString(py_.c_str()); - return 0; - } - - static int reload(const string& py_name_) - { - PyObject *pName = NULL, *pModule = NULL; - string err_msg; + static int init_py(); + static int final_py(); - pName = PyString_FromString(py_name_.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - return -1; - } + static int add_path(const std::string& path_); - PyObject *pNewMod = PyImport_ReloadModule(pModule); - Py_DECREF(pModule); - if (NULL == pNewMod) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - return -1; - } - Py_DECREF(pNewMod); - return 0; - } - static int load(const string& py_name_) - { - PyObject *pName = NULL, *pModule = NULL; - string err_msg; + static int run_string(const std::string& py_); + static int reload(const std::string& py_name_); + static int load(const std::string& py_name_); - pName = PyString_FromString(py_name_.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - return -1; - } - Py_DECREF(pModule); - return 0; - } //! 注册static function, template - ffpython_t& reg(T func_, const string& func_name_, string doc_ = "") + ffpython_t& reg(T func_, const std::string& func_name_, std::string doc_ = "") { reg_info_t tmp; tmp.args_num = pyext_func_traits_t::args_num(); @@ -668,8 +61,8 @@ class ffpython_t tmp.func_name= func_name_; tmp.func_impl_name = func_name_ + "_internal_"; tmp.doc = doc_; - tmp.doc_impl = string("internal use, please call ") + func_name_; - tmp.func_addr= (long)func_; + tmp.doc_impl = std::string("internal use, please call ") + func_name_; + tmp.func_addr= (PTR_NUMBER)func_; m_func_info.push_back(tmp); return *this; @@ -677,7 +70,7 @@ class ffpython_t //! 注册c++ class template - pyclass_regigster_tool_t& reg_class(const string& class_name_, string doc_ = "", string inherit_name_ = "") + pyclass_regigster_tool_t& reg_class(const std::string& class_name_, std::string doc_ = "", std::string inherit_name_ = "") { if (pyclass_base_info_t::pytype_info.class_name.empty() == false) throw runtime_error("this type has been registed"); @@ -706,26 +99,17 @@ class ffpython_t return m_all_pyclass.back(); } - //! 将需要注册的函数、类型注册到python虚拟机 - int init(const string& mod_name_, string doc_ = "") - { - m_mod_name = mod_name_; - m_mod_doc = doc_; - PyObject* m = init_method(); - init_pyclass(m); - return 0; - } //! 调用python函数,最多支持9个参数 template - RET_V call(const string& mod_name_, const string& func_) + RET_V call(const std::string& mod_name_, const std::string& func_) { pycall_arg_t args(0); pytype_tool_impl_t pyret; return pycall_t::call(mod_name_, func_, args, pyret); } template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1) + RET_V call(const std::string& mod_name_, const std::string& func_, const ARG1& a1) { pycall_arg_t args(1); args.add(a1); @@ -733,7 +117,7 @@ class ffpython_t return pycall_t::call(mod_name_, func_, args, pyret); } template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2) + RET_V call(const std::string& mod_name_, const std::string& func_, const ARG1& a1, const ARG2& a2) { pycall_arg_t args(2); args.add(a1).add(a2); @@ -741,7 +125,7 @@ class ffpython_t return pycall_t::call(mod_name_, func_, args, pyret); } template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3) + RET_V call(const std::string& mod_name_, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3) { pycall_arg_t args(3); args.add(a1).add(a2).add(a3); @@ -749,7 +133,7 @@ class ffpython_t return pycall_t::call(mod_name_, func_, args, pyret); } template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) + RET_V call(const std::string& mod_name_, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) { pycall_arg_t args(4); args.add(a1).add(a2).add(a3).add(a4); @@ -757,7 +141,7 @@ class ffpython_t return pycall_t::call(mod_name_, func_, args, pyret); } template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + RET_V call(const std::string& mod_name_, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, const ARG5& a5) { pycall_arg_t args(5); @@ -766,7 +150,7 @@ class ffpython_t return pycall_t::call(mod_name_, func_, args, pyret); } template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + RET_V call(const std::string& mod_name_, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, const ARG5& a5,const ARG6& a6) { pycall_arg_t args(6); @@ -775,7 +159,7 @@ class ffpython_t return pycall_t::call(mod_name_, func_, args, pyret); } template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + RET_V call(const std::string& mod_name_, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, const ARG5& a5,const ARG6& a6,const ARG7& a7) { pycall_arg_t args(7); @@ -785,7 +169,7 @@ class ffpython_t } template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + RET_V call(const std::string& mod_name_, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) { pycall_arg_t args(8); @@ -795,7 +179,7 @@ class ffpython_t } template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + RET_V call(const std::string& mod_name_, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) { pycall_arg_t args(9); @@ -805,14 +189,14 @@ class ffpython_t } //!call python class method begin****************************************************************** template - RET_V obj_call(PyObject* pobj, const string& func_) + RET_V obj_call(PyObject* pobj, const std::string& func_) { pycall_arg_t args(0); pytype_tool_impl_t pyret; return pycall_t::call_obj_method(pobj, func_, args, pyret); } template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1) + RET_V obj_call(PyObject* pobj, const std::string& func_, const ARG1& a1) { pycall_arg_t args(1); args.add(a1); @@ -820,7 +204,7 @@ class ffpython_t return pycall_t::call_obj_method(pobj, func_, args, pyret); } template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2) + RET_V obj_call(PyObject* pobj, const std::string& func_, const ARG1& a1, const ARG2& a2) { pycall_arg_t args(2); args.add(a1).add(a2); @@ -828,7 +212,7 @@ class ffpython_t return pycall_t::call_obj_method(pobj, func_, args, pyret); } template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3) + RET_V obj_call(PyObject* pobj, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3) { pycall_arg_t args(3); args.add(a1).add(a2).add(a3); @@ -836,7 +220,7 @@ class ffpython_t return pycall_t::call_obj_method(pobj, func_, args, pyret); } template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) + RET_V obj_call(PyObject* pobj, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) { pycall_arg_t args(4); args.add(a1).add(a2).add(a3).add(a4); @@ -844,7 +228,7 @@ class ffpython_t return pycall_t::call_obj_method(pobj, func_, args, pyret); } template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + RET_V obj_call(PyObject* pobj, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, const ARG5& a5) { pycall_arg_t args(5); @@ -853,7 +237,7 @@ class ffpython_t return pycall_t::call_obj_method(pobj, func_, args, pyret); } template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + RET_V obj_call(PyObject* pobj, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, const ARG5& a5,const ARG6& a6) { pycall_arg_t args(6); @@ -862,7 +246,7 @@ class ffpython_t return pycall_t::call_obj_method(pobj, func_, args, pyret); } template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + RET_V obj_call(PyObject* pobj, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, const ARG5& a5,const ARG6& a6,const ARG7& a7) { pycall_arg_t args(7); @@ -872,7 +256,7 @@ class ffpython_t } template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + RET_V obj_call(PyObject* pobj, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) { pycall_arg_t args(8); @@ -882,7 +266,7 @@ class ffpython_t } template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + RET_V obj_call(PyObject* pobj, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) { pycall_arg_t args(9); @@ -971,7 +355,7 @@ class ffpython_t } template - RET_V call_lambda(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + RET_V call_lambda(PyObject* pobj, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) { pycall_arg_t args(9); @@ -981,10 +365,10 @@ class ffpython_t } //!call python lambad function ennd ############################################################ template - RET_V get_global_var(const string& mod_name_, const string& var_name_) + RET_V get_global_var(const std::string& mod_name_, const std::string& var_name_) { PyObject *pName = NULL, *pModule = NULL; - string err_msg; + std::string err_msg; pName = PyString_FromString(mod_name_.c_str()); pModule = PyImport_Import(pName); @@ -1015,10 +399,10 @@ class ffpython_t } template - int set_global_var(const string& mod_name_, const string& var_name_, const T& val_) + int set_global_var(const std::string& mod_name_, const std::string& var_name_, const T& val_) { PyObject *pName = NULL, *pModule = NULL; - string err_msg; + std::string err_msg; pName = PyString_FromString(mod_name_.c_str()); pModule = PyImport_Import(pName); @@ -1035,10 +419,11 @@ class ffpython_t return ret != -1? 0: -1; } + template - RET_V getattr(PyObject* pModule, const string& var_name_) + RET_V getattr(PyObject* pModule, const std::string& var_name_) { - string err_msg; + std::string err_msg; if (NULL == pModule) { throw runtime_error("getattr object ptr null"); @@ -1061,6 +446,8 @@ class ffpython_t Py_XDECREF(pvalue); return pyret.get_value(); } + + void cache_pyobject(PyObject* pobj) { m_cache_pyobject.push_back(pobj); @@ -1077,2849 +464,29 @@ class ffpython_t } } private: - PyObject* init_method() - { - string mod_name_ = m_mod_name; - string doc_ = m_mod_doc; + //! 将需要注册的函数、类型注册到python虚拟机 + int init(const std::string& mod_name_, std::string doc_ = ""); + void init_method(); + void rename_method(); + int init_pyclass(); + void rename_pyclass(); + + + bool is_method_exist(const std::vector& src_, const std::string& new_); + bool is_property_exist(const std::vector& src_, const std::string& new_); + pyclass_regigster_tool_t* get_pyclass_info_by_name(const std::string& name_); - if (m_pymethod_defs.empty()) - { - m_pymethod_defs.reserve(m_func_info.size() + 1); - - for (size_t i = 0; i < m_func_info.size(); ++i) - { - PyMethodDef tmp = {m_func_info[i].func_impl_name.c_str(), m_func_info[i].func, - METH_VARARGS, m_func_info[i].doc_impl.c_str()}; - m_pymethod_defs.push_back(tmp); - } - PyMethodDef tmp = {NULL}; - m_pymethod_defs.push_back(tmp); - } - - PyObject* m = Py_InitModule3(m_mod_name.c_str(), &(m_pymethod_defs.front()), doc_.c_str()); - - for (size_t i = 0; i < m_func_info.size(); ++i) - { - string pystr_args; - string pystr_args_only_name; - for (int j = 0; j < m_func_info[i].args_num; ++j) - { - stringstream ss; - if (pystr_args.empty()) - { - ss << "a" << (j+1); - pystr_args += ss.str(); - } - else - { - ss << ", a" << (j+1); - pystr_args += ss.str(); - } - } - pystr_args_only_name = pystr_args; - for (int j = 0; j < m_func_info[i].option_args_num; ++j) - { - stringstream ss; - if (pystr_args.empty()) - { - ss << "a" << (m_func_info[i].args_num + j+1); - string tmp = ss.str(); - pystr_args_only_name += tmp; - pystr_args += tmp + " = None"; - } - else - { - ss << ", a" << (m_func_info[i].args_num + j+1); - string tmp = ss.str(); - pystr_args_only_name += tmp; - pystr_args += tmp + " = None"; - } - } - if (!pystr_args_only_name.empty()) - pystr_args_only_name += ","; - - char buff[1024]; - SAFE_SPRINTF(buff, sizeof(buff), - "_tmp_ff_ = None\nif '%s' in globals():\n\t_tmp_ff_ = globals()['%s']\n" - "def %s(%s):\n" - "\t'''%s'''\n" - "\treturn %s.%s(%ld,(%s))\n" - "import %s\n" - "%s.%s = %s\n" - "%s = None\n" - "if _tmp_ff_:\n\tglobals()['%s'] = _tmp_ff_\n_tmp_ff_ = None\n", - m_func_info[i].func_name.c_str(), m_func_info[i].func_name.c_str(), - m_func_info[i].func_name.c_str(), pystr_args.c_str(), - m_func_info[i].doc.c_str(), - m_mod_name.c_str(), m_func_info[i].func_impl_name.c_str(), m_func_info[i].func_addr, pystr_args_only_name.c_str(), - m_mod_name.c_str(), - m_mod_name.c_str(), m_func_info[i].func_name.c_str(), m_func_info[i].func_name.c_str(), - m_func_info[i].func_name.c_str(), - m_func_info[i].func_name.c_str() - ); - - //printf(buff); - PyRun_SimpleString(buff); - } - - return m; - } - int init_pyclass(PyObject* m) - { - for (size_t i = 0; i < m_all_pyclass.size(); ++i) - { - m_all_pyclass[i].static_pytype_info->mod_name = m_mod_name; - if (false == m_all_pyclass[i].inherit_name.empty())//! ���ڻ��� - { - pyclass_regigster_tool_t* inherit_class = get_pyclass_info_by_name(m_all_pyclass[i].inherit_name); - assert(inherit_class && "base class must be registed"); - for (size_t n = 0; n < inherit_class->methods_info.size(); ++n) - { - const string& method_name = inherit_class->methods_info[n].func_name; - if (false == is_method_exist(m_all_pyclass[i].methods_info, method_name)) - { - m_all_pyclass[i].methods_info.push_back(inherit_class->methods_info[n]); - } - } - for (size_t n = 0; n < inherit_class->propertys_info.size(); ++n) - { - const string& property_name = inherit_class->propertys_info[n].property_name; - if (false == is_property_exist(m_all_pyclass[i].propertys_info, property_name)) - { - m_all_pyclass[i].propertys_info.push_back(inherit_class->propertys_info[n]); - } - } - } - //! init class property - for (size_t j = 0; j < m_all_pyclass[i].propertys_info.size(); ++j) - { - PyGetSetDef tmp = {(char*)m_all_pyclass[i].propertys_info[j].property_name.c_str(), - m_all_pyclass[i].propertys_info[j].getter_func, - m_all_pyclass[i].propertys_info[j].setter_func, - (char*)m_all_pyclass[i].propertys_info[j].doc.c_str(), - m_all_pyclass[i].propertys_info[j].ptr - }; - m_all_pyclass[i].pyproperty_def.push_back(tmp); - } - PyGetSetDef tmp_property_def = {NULL}; - m_all_pyclass[i].pyproperty_def.push_back(tmp_property_def); - //! init class method - for (size_t j = 0; j < m_all_pyclass[i].methods_info.size(); ++j) - { - PyMethodDef tmp = {m_all_pyclass[i].methods_info[j].func_real_name.c_str(), - m_all_pyclass[i].methods_info[j].func, - METH_VARARGS, - m_all_pyclass[i].methods_info[j].doc.c_str() - }; - m_all_pyclass[i].pymethod_def.push_back(tmp); - - } - PyMethodDef tmp_del = {"delete", - m_all_pyclass[i].delete_func, - METH_VARARGS, - "delete obj" - }; - m_all_pyclass[i].pymethod_def.push_back(tmp_del); - PyMethodDef tmp_method_def = {NULL}; - m_all_pyclass[i].pymethod_def.push_back(tmp_method_def); - - m_all_pyclass[i].class_name_with_mod = m_mod_name + "." + m_all_pyclass[i].class_name; - m_all_pyclass[i].class_reel_name_with_mod = m_mod_name + "." + m_all_pyclass[i].class_real_name; +private: + std::string m_mod_name; + std::string m_mod_doc; + std::vector m_pymethod_defs; + std::vector m_func_info; + + //! reg class + std::vector m_all_pyclass; + //! cache some pyobject for optimize + std::vector m_cache_pyobject; +}; - PyTypeObject tmp_pytype_def = - { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - m_all_pyclass[i].class_reel_name_with_mod.c_str(), /*tp_name*/ - m_all_pyclass[i].type_size, /*tp_size*/ - 0, /*tp_itemsize*/ - (destructor)m_all_pyclass[i].dector, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - m_all_pyclass[i].doc.c_str(), /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - &(m_all_pyclass[i].pymethod_def.front()),//Noddy_methods, /* tp_methods */ - 0,//Noddy_members, /* tp_members */ - &(m_all_pyclass[i].pyproperty_def.front()),//Noddy_getseters, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)m_all_pyclass[i].init, /* tp_init */ - 0, /* tp_alloc */ - m_all_pyclass[i].ctor, /* tp_new */ - }; - m_all_pyclass[i].pytype_def = tmp_pytype_def; - m_all_pyclass[i].static_pytype_info->pytype_def = &m_all_pyclass[i].pytype_def; - cpp_to_pyclass_reg_info_t::add(m_all_pyclass[i].class_name, m_all_pyclass[i].inherit_name, &m_all_pyclass[i].pytype_def); - - if (PyType_Ready((PyTypeObject *)(&(m_all_pyclass[i].pytype_def))) < 0) - return -1; - PyObject* tmpP = (PyObject*)(&(m_all_pyclass[i].pytype_def)); - Py_INCREF(tmpP); - PyModule_AddObject(m, m_all_pyclass[i].class_real_name.c_str(), (PyObject *)&m_all_pyclass[i].pytype_def); - - stringstream str_def_args; - stringstream str_init_args; - for (int a = 0; a < m_all_pyclass[i].args_num; ++a) - { - str_def_args << "a"<<(a+1)<<","; - str_init_args << "a"<<(a+1)<<","; - } - for (int b = 0; b < m_all_pyclass[b].option_args_num; ++b) - { - str_def_args << "a"<<(m_all_pyclass[i].args_num+ b+1)<<" = None,"; - str_init_args << "a"<<(m_all_pyclass[i].args_num+ b+1)<<","; - } - - char buff[1024]; - SAFE_SPRINTF(buff, sizeof(buff), - "_tmp_ff_ = None\nif '%s' in globals():\n\t_tmp_ff_ = globals()['%s']\n" - "import %s\n" - "class %s(object):\n" - "\t'''%s'''\n" - "\tdef __init__(self, %s assign_obj_ = 0):\n"//! ����init���� - "\t\t'''%s'''\n" - "\t\tif True == isinstance(assign_obj_, %s):\n" - "\t\t\tself.obj = assign_obj_\n" - "\t\t\treturn\n" - "\t\tself.obj = %s(0,(%s))\n", - m_all_pyclass[i].class_name.c_str(), m_all_pyclass[i].class_name.c_str(), - m_mod_name.c_str(), - m_all_pyclass[i].class_name.c_str(), - m_all_pyclass[i].doc.c_str(), - str_def_args.str().c_str(), - "init class", - m_all_pyclass[i].class_reel_name_with_mod.c_str(), - m_all_pyclass[i].class_reel_name_with_mod.c_str(), str_init_args.str().c_str() - ); - - string gen_class_str = buff; - SAFE_SPRINTF(buff, sizeof(buff), - "\tdef delete(self):\n"//! ����init���� - "\t\t'''delete obj'''\n" - "\t\tself.obj.delete()\n"); - gen_class_str += buff; - //! 增加析构函数 - //! 增加属性 - for (size_t c = 0; c < m_all_pyclass[i].propertys_info.size(); ++c) - { - SAFE_SPRINTF(buff, sizeof(buff), - "\tdef get_%s(self):\n" - "\t\treturn self.obj.%s\n" - "\tdef set_%s(self, v):\n" - "\t\tself.obj.%s = v\n" - "\t@property\n" - "\tdef %s(self):\n" - "\t\treturn self.obj.%s\n" - "\t@%s.setter\n" - "\tdef %s(self, v):\n" - "\t\tself.obj.%s = v\n", - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str() - ); - gen_class_str += buff; - } - - for (size_t m = 0; m < m_all_pyclass[i].methods_info.size(); ++m) - { - string pystr_args; - string pystr_args_only_name; - for (int j = 0; j < m_all_pyclass[i].methods_info[m].args_num; ++j) - { - stringstream ss; - if (pystr_args.empty()) - { - ss << "a" << (j+1); - pystr_args += ss.str(); - } - else - { - ss << ", a" << (j+1); - pystr_args += ss.str(); - } - } - pystr_args_only_name = pystr_args; - for (int j = 0; j < m_all_pyclass[i].methods_info[m].option_args_num; ++j) - { - stringstream ss; - if (pystr_args.empty()) - { - ss << "a" << (m_all_pyclass[i].methods_info[m].args_num + j+1); - string tmp = ss.str(); - pystr_args_only_name += tmp; - pystr_args += tmp + " = None"; - } - else - { - ss << ", a" << (m_all_pyclass[i].methods_info[m].args_num + j+1); - string tmp = ss.str(); - pystr_args_only_name += tmp; - pystr_args += tmp + " = None"; - } - } - if (!pystr_args_only_name.empty()) - pystr_args_only_name += ","; - - SAFE_SPRINTF(buff, sizeof(buff), - "\tdef %s(self,%s):\n" - "\t\t'''%s'''\n" - "\t\treturn self.obj.%s(%ld,(%s))\n" - ,m_all_pyclass[i].methods_info[m].func_name.c_str(), pystr_args.c_str(), - m_all_pyclass[i].methods_info[m].doc.c_str(), - m_all_pyclass[i].methods_info[m].func_real_name.c_str(), m_all_pyclass[i].methods_info[m].func_addr, pystr_args_only_name.c_str() - ); - gen_class_str += buff; - } - SAFE_SPRINTF(buff, sizeof(buff), - "%s.%s = %s\n" - "%s = None\n" - "if _tmp_ff_:\n\tglobals()['%s'] = _tmp_ff_\n_tmp_ff_ = None\n", - m_mod_name.c_str(), m_all_pyclass[i].class_name.c_str(), m_all_pyclass[i].class_name.c_str(), - m_all_pyclass[i].class_name.c_str(), - m_all_pyclass[i].class_name.c_str() - ); - gen_class_str += buff; - //printf(gen_class_str.c_str()); - PyRun_SimpleString(gen_class_str.c_str()); - } - return 0; - } - - - - - bool is_method_exist(const vector& src_, const string& new_) - { - for (size_t i = 0; i < src_.size(); ++i) - { - if (new_ == src_[i].func_name) - { - return true; - } - } - return false; - } - bool is_property_exist(const vector& src_, const string& new_) - { - for (size_t i = 0; i < src_.size(); ++i) - { - if (new_ == src_[i].property_name) - { - return true; - } - } - return false; - } - pyclass_regigster_tool_t* get_pyclass_info_by_name(const string& name_) - { - for (size_t i = 0; i < m_all_pyclass.size(); ++i) - { - if (m_all_pyclass[i].class_name == name_) - { - return &(m_all_pyclass[i]); - } - } - return NULL; - } - - - - -private: - string m_mod_name; - string m_mod_doc; - vector m_pymethod_defs; - vector m_func_info; - - //! reg class - vector m_all_pyclass; - //! cache some pyobject for optimize - vector m_cache_pyobject; -}; - - -template -struct type_ref_traits_t -{ - typedef T value_t; - typedef T& ref_t; - value_t value; -}; -template -struct type_ref_traits_t -{ - typedef T value_t; - typedef T& ref_t; - value_t value; -}; -template -struct type_ref_traits_t -{ - typedef T value_t; - typedef T& ref_t; - value_t value; -}; -//! 用于判断是否是可选参数 -template -struct pyoption_traits_t -{ - static int is() { return 0;} -}; -template -struct pyoption_traits_t > -{ - static int is() { return 1;} -}; - - -template<>//typename T> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const long& val_) - { - return PyLong_FromLong(long(val_)); - } - static int pyobj_to_cppobj(PyObject *pvalue_, long& m_ret) - { - if (true == PyLong_Check(pvalue_)) - { - m_ret = (long)PyLong_AsLong(pvalue_); - return 0; - } - else if (true == PyInt_Check(pvalue_)) - { - m_ret = (long)PyInt_AsLong(pvalue_); - return 0; - } - return -1; - } - static const char* get_typename() { return "long";} -}; - -#define IMPL_INT_CODE(X) \ -template<> \ -struct pytype_traits_t \ -{ \ - static PyObject* pyobj_from_cppobj(const X& val_) \ - { \ - return PyInt_FromLong(long(val_)); \ - } \ - static int pyobj_to_cppobj(PyObject *pvalue_, X& m_ret) \ - { \ - if (true == PyLong_Check(pvalue_)) \ - { \ - m_ret = (X)PyLong_AsLong(pvalue_); \ - return 0; \ - } \ - else if (true == PyInt_Check(pvalue_)) \ - { \ - m_ret = (X)PyInt_AsLong(pvalue_); \ - return 0; \ - } \ - return -1; \ - } \ - static const char* get_typename() { return #X;} \ -}; - -IMPL_INT_CODE(int) -IMPL_INT_CODE(unsigned int) -IMPL_INT_CODE(short) -IMPL_INT_CODE(unsigned short) -IMPL_INT_CODE(char) -IMPL_INT_CODE(unsigned char) - -#ifdef _WIN32 -IMPL_INT_CODE(unsigned long) -#else -#ifndef __x86_64__ -IMPL_INT_CODE(int64_t) -#endif -IMPL_INT_CODE(uint64_t) -#endif - -template -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const T* val_) - { - const string& mod_name = pyclass_base_info_t::pytype_info.mod_name; - const string& class_name = pyclass_base_info_t::pytype_info.class_name; - PyObject *pName = NULL, *pModule = NULL, *pValue = NULL; - - if (class_name.empty()) - return pytype_traits_t::pyobj_from_cppobj(long(val_)); - - pName = PyString_FromString(mod_name.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - if (PyErr_Occurred()) - PyErr_Print(); - fprintf(stderr, "Failed to load \"%s\"\n", mod_name.c_str()); - assert(NULL && "this can not be happened"); - return NULL; - } - PyObject *pyclass = PyObject_GetAttrString(pModule, class_name.c_str()); - if (pyclass && PyCallable_Check(pyclass)) { - PyObject *pArgs = PyTuple_New(pyclass_base_info_t::pytype_info.total_args_num+1); - for (int i = 0; i< pyclass_base_info_t::pytype_info.total_args_num; ++i) - { - PyTuple_SetItem(pArgs, i, pytype_traits_t::pyobj_from_cppobj(0)); - } - - PyObject *palloc = pyclass_base_info_t::alloc_obj(pyclass_base_info_t::pytype_info.pytype_def, NULL, NULL); - typename pyclass_base_info_t::obj_data_t* pdest_obj = (typename pyclass_base_info_t::obj_data_t*)palloc; - //pdest_obj->obj = val_; - ::memcpy((void*)&pdest_obj->obj, (const void*)&val_, sizeof(pdest_obj->obj)); - pdest_obj->disable_auto_release(); - PyTuple_SetItem(pArgs, pyclass_base_info_t::pytype_info.total_args_num, palloc); - pValue = PyObject_CallObject(pyclass, pArgs); - Py_XDECREF(pArgs); - } - - Py_XDECREF(pyclass); - Py_DECREF(pModule); - return pValue; - } - - static int pyobj_to_cppobj(PyObject *pvalue_, T*& m_ret) - { - PyObject *pysrc = PyObject_GetAttrString(pvalue_, "obj"); - //!PyObject_TypeCheck(pysrc, pyclass_base_info_t::pytype_info.pytype_def)) { - if (NULL == pysrc || false == cpp_to_pyclass_reg_info_t::is_instance(pysrc, pyclass_base_info_t::pytype_info.class_name)) - { - Py_XDECREF(pysrc); - return -1; - } - typename pyclass_base_info_t::obj_data_t* pdest_obj = (typename pyclass_base_info_t::obj_data_t*)pysrc; - - m_ret = pdest_obj->obj; - Py_XDECREF(pysrc); - return 0; - } - - static const char* get_typename() { return pyclass_base_info_t::pytype_info.class_name.c_str();} -}; - -template -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(T* val_) - { - return pytype_traits_t::pyobj_from_cppobj(val_); - } - static int pyobj_to_cppobj(PyObject *pvalue_,T*& m_ret) - { - return pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret); - } - static const char* get_typename() { return pyclass_base_info_t::pytype_info.class_name.c_str();} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(PyObject* val_) - { - return val_; - } - static int pyobj_to_cppobj(PyObject *pvalue_, PyObject*& m_ret) - { - m_ret = pvalue_; - return 0; - } - static const char* get_typename() { return "PyObject";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const char* const val_) - { - return PyString_FromString(val_); - } - /* - static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) - { - if (true == PyString_Check(pvalue_)) - { - m_ret = PyString_AsString(pvalue_); - return 0; - } - return -1; - } - */ - static const char* get_typename() { return "string";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const char*& val_) - { - return PyString_FromString(val_); - } - /* - static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) - { - if (true == PyString_Check(pvalue_)) - { - m_ret = PyString_AsString(pvalue_); - return 0; - } - return -1; - } - */ - static const char* get_typename() { return "string";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(bool val_) - { - if (val_) - { - return Py_BuildValue("i", 1); - } - return Py_BuildValue("i", 0); - } - static int pyobj_to_cppobj(PyObject *pvalue_, bool& m_ret) - { - if (Py_False == pvalue_|| Py_None == pvalue_) - { - m_ret = false; - } - else - { - m_ret = true; - } - return 0; - } - static const char* get_typename() { return "bool";} -}; - -template -struct pytype_traits_t > -{ - static int pyobj_to_cppobj(PyObject *pvalue_, pyoption_t& m_ret) - { - if (Py_None == pvalue_) - { - return 0; - } - else if (0 == pytype_traits_t::value_t>::pyobj_to_cppobj(pvalue_, m_ret.value())) - { - m_ret.set(); - return 0; - } - return -1; - } - static const char* get_typename() { return "pyoption_t";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const string& val_) - { - return PyString_FromStringAndSize(val_.c_str(), val_.size()); - } - static int pyobj_to_cppobj(PyObject *pvalue_, string& m_ret) - { - if (true == PyString_Check(pvalue_)) - { - char* pDest = NULL; - Py_ssize_t nLen = 0; - PyString_AsStringAndSize(pvalue_, &pDest, &nLen); - - m_ret.assign(pDest, nLen); - return 0; - } - else if (true == PyUnicode_Check(pvalue_)) - { - char* pDest = NULL; - Py_ssize_t nLen = 0; - PyString_AsStringAndSize(pvalue_, &pDest, &nLen); - m_ret.assign(pDest, nLen); - return 0; - /* -#ifdef _WIN32 - PyObject* retStr = PyUnicode_AsEncodedString(pvalue_, "gbk", ""); -#else - PyObject* retStr = PyUnicode_AsUTF8String(pvalue_); -#endif - if (retStr) - { - m_ret = PyString_AsString(retStr); - Py_XDECREF(retStr); - return 0; - } - */ - } - return -1; - } - static const char* get_typename() { return "string";} -}; - -#ifdef _WIN32 -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const wstring& wstr) - { - return PyUnicode_FromWideChar(wstr.c_str(), wstr.length()); - } - static int pyobj_to_cppobj(PyObject *pvalue_, wstring& wstr_ret) - { - if (true == PyString_Check(pvalue_)) - { - PyObject* retStr = PyUnicode_FromObject(pvalue_); - if (retStr) - { - int n = PyUnicode_GetSize(retStr); - wstr_ret.resize(n); - n = PyUnicode_AsWideChar((PyUnicodeObject*)retStr, &(wstr_ret[0]), n); - Py_XDECREF(retStr); - return 0; - } - return 0; - } - else if (true == PyUnicode_Check(pvalue_)) - { - int n = PyUnicode_GetSize(pvalue_); - wstr_ret.resize(n); - n = PyUnicode_AsWideChar((PyUnicodeObject*)pvalue_, &(wstr_ret[0]), n); - return 0; - } - return -1; - } - static const char* get_typename() { return "wstring";} -}; -#endif - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(float val_) - { - return PyFloat_FromDouble(double(val_)); - } - static int pyobj_to_cppobj(PyObject *pvalue_, float& m_ret) - { - if (true == PyFloat_Check(pvalue_)) - { - m_ret = (float)PyFloat_AsDouble(pvalue_); - return 0; - } - return -1; - } - static const char* get_typename() { return "float";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(double val_) - { - return PyFloat_FromDouble(val_); - } - static int pyobj_to_cppobj(PyObject *pvalue_, double& m_ret) - { - if (true == PyFloat_Check(pvalue_)) - { - m_ret = PyFloat_AsDouble(pvalue_); - return 0; - } - return -1; - } - static const char* get_typename() { return "double";} -}; - -template -struct pytype_traits_t > -{ - static PyObject* pyobj_from_cppobj(const vector& val_) - { - PyObject* ret = PyList_New(val_.size()); - for (size_t i = 0; i < val_.size(); ++i) - { - PyList_SetItem(ret, i, pytype_traits_t::pyobj_from_cppobj(val_[i])); - } - return ret; - } - static int pyobj_to_cppobj(PyObject *pvalue_, vector& m_ret) - { - m_ret.clear(); - if (true == PyTuple_Check(pvalue_)) - { - int n = PyTuple_Size(pvalue_); - for (int i = 0; i < n; ++i) - { - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyTuple_GetItem(pvalue_, i))) - { - return -1; - } - m_ret.push_back(ret_tool.get_value()); - } - return 0; - } - else if (true == PyList_Check(pvalue_)) - { - int n = PyList_Size(pvalue_); - for (int i = 0; i < n; ++i) - { - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyList_GetItem(pvalue_, i))) - { - return -1; - } - m_ret.push_back(ret_tool.get_value()); - } - return 0; - } - return -1; - } - static const char* get_typename() { return "vector";} -}; -template -struct pytype_traits_t > -{ - static PyObject* pyobj_from_cppobj(const list& val_) - { - size_t n = val_.size(); - PyObject* ret = PyList_New(n); - int i = 0; - for (typename list::const_iterator it = val_.begin(); it != val_.end(); ++it) - { - PyList_SetItem(ret, i++, pytype_traits_t::pyobj_from_cppobj(*it)); - } - return ret; - } - static int pyobj_to_cppobj(PyObject *pvalue_, list& m_ret) - { - pytype_tool_impl_t ret_tool; - if (true == PyTuple_Check(pvalue_)) - { - int n = PyTuple_Size(pvalue_); - for (int i = 0; i < n; ++i) - { - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyTuple_GetItem(pvalue_, i))) - { - return -1; - } - m_ret.push_back(ret_tool.get_value()); - } - return 0; - } - else if (true == PyList_Check(pvalue_)) - { - int n = PyList_Size(pvalue_); - for (int i = 0; i < n; ++i) - { - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyList_GetItem(pvalue_, i))) - { - return -1; - } - m_ret.push_back(ret_tool.get_value()); - } - return 0; - } - return -1; - } - static const char* get_typename() { return "list";} -}; -template -struct pytype_traits_t > -{ - static PyObject* pyobj_from_cppobj(const set& val_) - { - PyObject* ret = PySet_New(NULL); - for (typename set::const_iterator it = val_.begin(); it != val_.end(); ++it) - { - PyObject *v = pytype_traits_t::pyobj_from_cppobj(*it); - PySet_Add(ret, v); - Py_DECREF(v); - } - return ret; - } - static int pyobj_to_cppobj(PyObject *pvalue_, set& m_ret) - { - m_ret.clear(); - pytype_tool_impl_t ret_tool; - PyObject *iter = PyObject_GetIter(pvalue_); - PyObject *item = NULL; - while (NULL != iter && NULL != (item = PyIter_Next(iter))) - { - T tmp(); - if (pytype_traits_t::pyobj_to_cppobj(item, tmp)) - { - Py_DECREF(item); - Py_DECREF(iter); - return -1; - } - m_ret.insert(tmp); - Py_DECREF(item); - } - if (iter) - { - Py_DECREF(iter); - return 0; - } - return -1; - } - static const char* get_typename() { return "set";} -}; -template -struct pytype_traits_t > -{ - static PyObject* pyobj_from_cppobj(const map& val_) - { - PyObject* ret = PyDict_New(); - for (typename map::const_iterator it = val_.begin(); it != val_.end(); ++it) - { - PyObject *k = pytype_traits_t::pyobj_from_cppobj(it->first); - PyObject *v = pytype_traits_t::pyobj_from_cppobj(it->second); - PyDict_SetItem(ret, k, v); - Py_DECREF(k); - Py_DECREF(v); - } - return ret; - } - static int pyobj_to_cppobj(PyObject *pvalue_, map& m_ret) - { - m_ret.clear(); - pytype_tool_impl_t ret_tool_T; - pytype_tool_impl_t ret_tool_R; - if (true == PyDict_Check(pvalue_)) - { - PyObject *key = NULL, *value = NULL; - Py_ssize_t pos = 0; - - while (PyDict_Next(pvalue_, &pos, &key, &value)) - { - T tmp_key; - R tmp_value; - if (pytype_traits_t::pyobj_to_cppobj(key, tmp_key) || - pytype_traits_t::pyobj_to_cppobj(value, tmp_value)) - { - return -1; - } - m_ret[tmp_key] = tmp_value; - } - return 0; - } - return -1; - } - static const char* get_typename() { return "map";} -}; - -//! ��ȡpython�����ķ���ֵ,������ -template -class pytype_tool_impl_t: public pytype_tool_t -{ -public: - pytype_tool_impl_t():m_ret(){} - - virtual int parse_value(PyObject *pvalue_) - { - if (pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret)) - { - return -1; - } - return 0; - } - - const T& get_value() const { return m_ret; } - virtual const char* return_type() {return pytype_traits_t::get_typename();} -private: - T m_ret; -}; - -template<> -class pytype_tool_impl_t: public pytype_tool_t -{ -public: - pytype_tool_impl_t():m_ret(){} - - virtual int parse_value(PyObject *pvalue_) - { - return 0; - } - - const cpp_void_t& get_value() const { return m_ret; } - virtual const char* return_type() { return "void";} -private: - cpp_void_t m_ret; -}; -template -class pytype_tool_impl_t: public pytype_tool_t -{ -public: - pytype_tool_impl_t():m_ret(){} - - virtual int parse_value(PyObject *pvalue_) - { - if (pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret)) - { - return -1; - } - return 0; - } - - T* get_value() const { return m_ret; } -private: - T* m_ret; -}; - - -template<> -class pytype_tool_impl_t: public pytype_tool_t -{ -public: - pytype_tool_impl_t():m_ret(){} - - virtual int parse_value(PyObject *pvalue_) - { - m_ret = pvalue_; - return 0; - } - - PyObject*& get_value() { return m_ret; } - bool need_release() { return false; } -private: - PyObject* m_ret; -}; - - -template -const T& pycall_t::call(const string& mod_name_, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) -{ - PyObject *pName = NULL, *pModule = NULL; - string err_msg; - - pName = PyString_FromString(mod_name_.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - return pyret.get_value(); - } - - call_func(pModule, mod_name_, func_name_, pyarg_, pyret, err_msg); - Py_DECREF(pModule); - - if (!err_msg.empty()) - { - throw runtime_error(err_msg.c_str()); - } - return pyret.get_value(); -} -template -const T& pycall_t::call_obj_method(PyObject *pObj, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) -{ - string err_msg; - if (NULL == pObj) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - return pyret.get_value(); - } - - static string mod_name_ = "NaN"; - call_func(pObj, mod_name_, func_name_, pyarg_, pyret, err_msg); - - if (!err_msg.empty()) - { - throw runtime_error(err_msg.c_str()); - } - return pyret.get_value(); -} - -template -const T& pycall_t::call_lambda(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) -{ - string err_msg; - if (NULL == pFunc) - { - err_msg = "can not call null PyObject"; - throw runtime_error(err_msg.c_str()); - return pyret.get_value(); - } - - call_func_obj(pFunc, pyarg_, pyret, err_msg); - - if (!err_msg.empty()) - { - throw runtime_error(err_msg.c_str()); - } - return pyret.get_value(); -} - - -//! 用于扩展python的工具类,用来解析参数 -struct pyext_tool_t -{ - pyext_tool_t(PyObject* args_): - m_args(args_), - m_arg_tuple(NULL), - m_index(0), - m_err(false), - m_func_addr(0) - { - if (!PyArg_ParseTuple(args_, "lO", &m_func_addr, &m_arg_tuple)) { - m_err = true; - return; - } - if (NULL == m_arg_tuple || false == PyTuple_Check(m_arg_tuple)) - { - PyErr_SetString(PyExc_TypeError, "arg type invalid(shoule func_name, args tuple)"); - m_err = true; - return; - } - m_size = PyTuple_Size(m_arg_tuple); - } - - template - pyext_tool_t& parse_arg(T& ret_arg_) - { - //typedef typename type_ref_traits_t::value_t value_t; - if (false == m_err) - { - if (m_index >= m_size) - { - stringstream ss; - ss << "param num invalid, only["<< m_index + 1 <<"] provided"; - PyErr_SetString(PyExc_TypeError, ss.str().c_str()); - m_err = true; - return *this; - } - - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyTuple_GetItem(m_arg_tuple, m_index))) - { - stringstream ss; - ss << "param[" << m_index + 1 << "] type invalid, "<< pytype_traits_t::get_typename() << " needed"; - PyErr_SetString(PyExc_TypeError, ss.str().c_str()); - m_err = true; - return *this; - } - ++m_index; - ret_arg_ = ret_tool.get_value(); - } - return *this; - } - - bool is_err() const { return m_err;} - long get_func_addr() const { return m_func_addr;} - - template - FUNC get_func_ptr() const - { - FUNC f = NULL; - ::memcpy((void*)&f, (const void*)&m_func_addr, sizeof(m_func_addr)); - return f; - } - PyObject* m_args; - PyObject* m_arg_tuple; - int m_index; - int m_size; - bool m_err;//! 是否异常 - long m_func_addr; -}; - - -//! 用于扩展python,生成pyobject类型的返回值给python -template -struct pyext_return_tool_t -{ - //! 用于静态方法 - template - static PyObject* route_call(F f) - { - return pytype_traits_t::pyobj_from_cppobj(f()); - } - template - static PyObject* route_call(F f, ARG1& a1) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value, a8.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value, a8.value, a9.value)); - } - //! 用于成员方法 - template - static PyObject* route_method_call(O o, F f) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)()); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value, a8.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value, a8.value, a9.value)); - } -}; - -template<> -struct pyext_return_tool_t -{ - template - static PyObject* route_call(F f) - { - f(); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1) - { - f(a1.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2) - { - f(a1.value, a2.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3) - { - f(a1.value, a2.value, a3.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) - { - f(a1.value, a2.value, a3.value, a4.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f) - { - (o->*f)(); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1) - { - (o->*f)(a1.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2) - { - (o->*f)(a1.value, a2.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3) - { - (o->*f)(a1.value, a2.value, a3.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); - Py_RETURN_NONE; - } -}; - - -//! 用于扩展python,traits出注册给python的函数接口 -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(); - static int args_num() { return 0;} - static int option_args_num() { return 0;} - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - return pyext_return_tool_t::route_call(f); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1); - static int args_num(){ return 1-option_args_num();} - static int option_args_num() - { - return pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - if (pyext_tool.parse_arg(a1.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2); - static int args_num() { return 2 - option_args_num();} - static int option_args_num() - { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3); - static int args_num() { return 3-option_args_num();} - static int option_args_num() - { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3); - } -}; -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4); - static int args_num() { return 4-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5); - static int args_num() { return 5-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); - static int args_num() { return 6-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); - static int args_num() { return 7-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); - static int args_num() { return 8-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7, a8); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); - static int args_num() { return 9-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - type_ref_traits_t a9; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7, a8, a9); - } -}; - -//! ��������pyclass ��ʼ������ -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - - self->obj = new CLASS_TYPE(); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - if (pyext_tool.parse_arg(a1.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - type_ref_traits_t a9; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); - return 0; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(); - static int args_num() { return 0;} - static int option_args_num() { return 0;} - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1); - static int args_num() { return 1-option_args_num();} - static int option_args_num() { return pyoption_traits_t::value_t>::is();} - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - if (pyext_tool.parse_arg(a1.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2); - static int args_num() { return 2-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2);; - } -}; - - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3); - static int args_num() { return 3-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4); - static int args_num() { return 4-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5); - static int args_num() { return 5-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); - static int args_num() { return 6-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); - static int args_num() { return 7-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); - static int args_num() { return 8-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8);; - } -}; - - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); - static int args_num() { return 9-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - type_ref_traits_t a9; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8, a9);; - } -}; - -//! const类型成员函数--------------------------------------------------------------------------------------------- - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)() const; - static int args_num() { return 0;} - static int option_args_num() { return 0;} - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1) const; - static int args_num() { return 1-option_args_num();} - static int option_args_num() { return pyoption_traits_t::value_t>::is();} - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - if (pyext_tool.parse_arg(a1.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2) const; - static int args_num() { return 2-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2);; - } -}; - - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3) const; - static int args_num() { return 3-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4) const; - static int args_num() { return 4-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5) const; - static int args_num() { return 5-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) const; - static int args_num() { return 6-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) const; - static int args_num() { return 7-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8) const; - static int args_num() { return 8-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8);; - } -}; - - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9) const; - static int args_num() { return 9-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - type_ref_traits_t a9; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8, a9);; - } -}; #endif diff --git a/fftest.py b/fftest.py index 94e7efe..24e2f77 100644 --- a/fftest.py +++ b/fftest.py @@ -15,14 +15,15 @@ def test_return_stl(): return ret def test_reg_function(): - import ext1 - ext1.print_val(123, 45.6 , "----789---", [3.14]) - ret = ext1.return_stl() + import cppext + cppext.print_val(123, 45.6 , "----789---", [3.14]) + ret = cppext.return_stl() print('test_reg_function', ret) def test_register_base_class(): - import ext2 - foo = ext2.foo_t(20130426) + import cppext + foo = cppext.foo_t(20130426) + print("test_register_base_class get_val:", foo.get_value()) foo.set_value(778899) print("test_register_base_class get_val:", foo.get_value(), foo.m_value) @@ -30,8 +31,8 @@ def test_register_base_class(): print('test_register_base_class test_register_base_class', foo) def test_register_inherit_class(): - import ext2 - dumy = ext2.dumy_t(20130426) + import cppext + dumy = cppext.dumy_t(20130426) print("test_register_inherit_class get_val:", dumy.get_value()) dumy.set_value(778899) print("test_register_inherit_class get_val:", dumy.get_value(), dumy.m_value) @@ -45,7 +46,7 @@ def test_cpp_obj_to_py_ext(foo): print('test_cpp_obj_to_py_ext', k, foo[k].m_value) def test_cpp_obj_to_py(foo): - import ext2 + import cppext print("test_cpp_obj_to_py get_val:", foo.get_value()) foo.set_value(778899) print("test_cpp_obj_to_py get_val:", foo.get_value(), foo.m_value) @@ -54,13 +55,13 @@ def test_cpp_obj_to_py(foo): print('test_cpp_obj_to_py test_register_base_class', foo) def test_cpp_obj_py_obj(dumy): - import ext2 + import cppext print("test_cpp_obj_py_obj get_val:", dumy.get_value()) dumy.set_value(778899) print("test_cpp_obj_py_obj get_val:", dumy.get_value(), dumy.m_value) dumy.test_stl({"key": [11,22,33] }) dumy.dump() - ext2.obj_test(dumy) + cppext.obj_test(dumy) print('test_cpp_obj_py_obj', dumy) return dumy diff --git a/vs2008.x86/ffpython.ncb b/vs2008.x86/ffpython.ncb deleted file mode 100644 index 84a8fce1e43e7aca9ec62ca877a4e84d11b45993..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2919424 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

-o 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 z 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 z zE;a3Rwf`*XDK-hJ$(@YxD?hwM@A>Dy0YV>oqrLBr!)krwMD;OJ zeZ&8~N2>P_%8`!V_qz8G{=3*AtycL@*#>1k``VGOK<#>{L_{@9s#?yQIwDwFHH-58 zGH>a6<=0RxsTYEJZw69Wo=SEH_=swSQIh!D!4W}|^c4-7>DwqhMix4=3(M%P+&cAj z?R@&kO&#{N@eSOFzEj9Lhi_Z!9;Oj$6Drh*^&UbB9?-4jIR2r}Z2#Zy#D9bgPHbE% z*Am<&HYoDZ?h6#vs?&cJ`zWN+aByFQ$jW0_@fC2s&RAls_^#k$X#ua(+p&r7OP9B# zXHIiNbD>q93Q*h8)B@emSl8Sc-q>3j*YLvnLcCj>f;g^$!;a(BkqQ-UN1fra6H~gH znv1#@C9$?>Ar&guj{OD^?tLL4LNfa8lb^Et^!&UTdr#Z9^Z@0jblY1SRp34JejndC z9)7dW-e*ZiXF9s;_lm^30ycA1yKfe&SDo@ToqW)3qA4_VATI?R zyZ@4nk_o0!)ofR)ynYc)6|~NqPD`Ey7~*iI1UgjE#a;{~ITRLWq@=0b3sE-Pc)S`~ zmQ*a^m8*ax9t3}jYwCfN2iqrVQqH$}x)!af$P06{M4C!wV9Kr(cZh zgo>x}(!jue!)CmaDlAx{i6_s41rDNq@3DJe1JUd(+zh4!tMRRK!1V3Jia9&iqy);&u+t459w8I9CuM) zSlrf(7rMy>jd~83l=n#}3*mRb6`qC99oH?QX^xfasFJjAoM~MyeVT^x3)(x{7IoCM zad-o`bl^rt|L1Lvh+u(9EaP`-v*n{x3;zBJBr1oeA~kP z@O3R8dPD)$2p3gqy&kLUem(PC6_3V=>MD!~Kb&RN*p?gEvDoauwH{-tz^TAX0riFg zdWjECs*2*#_842MSVvo1k!N6_?dPJp&?&N6OCrP*9Oh&}ifK?Ykj8_8XyJ->Q-h_y zCz}a(ETUnCcScoDS?^e^o68PsC^Q#}g?;wL(FHh2LEMS!*21#hHUYECxww~@N-*0j z?j=5eQ`cMo7$NME9cS{VY-V-7cE+q}^gDUxOq>~Z0FI@^S0(GZ=~A%;f}=FnT)5mf zn3efbd7_OXkEW`Zl*O}rHI3oYLOq8i4>eQOtxTFliyG?SGw@XCfjAsZ=Q#CsJ*k|B zGxKCxYlHfBFwUZAZuamY{?¥hoKh`ldjo!#)N~sAYp9j@MY&S;YB97#;N%f4+KY zQQ@!XFG28csZ(bZezGK?XT3)5kWDg%nD>B4LX~oYnXy;x2)IdiHtuRflgcOMCBou( zqN{WiAN4OpMFm-(yvHekKam8IRArhrxDul)r9rYD8yj=(7XXC0WH#9dK z>P$b}D?e-6ym^y%nl{gUO7iADnZ5h0X>(^(yANm0nLVv`^4$6E)9Tv!HD2xNIWuQY zuEoPagNElO(rGL~RaI`%B*F$_J!|q_^dsBgPb6fz=J5E1fWq=SPumM;!PL}Dn~M{b zXHK5IE6dmHKD)Y>>lO9f;vC|CP&8wMQJq_KRGrM-~oSAG`_po8ZEJ5S@hiu8C z{ZvZy^bm=!m5-2=HIK#SE5T&KGlsq*rHas)7Tf$Du-k1o*h_G#Y*F6X%~_AIqe(3G z@K^5?KK3((Ol-4YF&**O7gEmDLQ?dt#$34uro#$({`#qTZ1=)Oa=2EKT86K~ z&&>!}N=OCB31(F96inrnRR{&k6uD6@snyS zYNe_avDlZUp2Oy8DmeNetOf}EwtA4s!e0yu2@UCW(vsNTPuj{QyBZsQ_)=3#yPK<+ z3-%g^yGO!TeG!I;bC!cG4waA`%7H*$u#_Izg@{vURVP#<7RS)00$9Qbsn#Zjm&SR6 zP0)HxIEMcK99byk&V8zY2m&GG0YXvCEV09?u&Qj~mY}i0_G3q|QDcX*5o5PwBSz!@ zn31-ZQ%}QXP6bzobd$>ynFakw-j+?#q;gOS7Lz2G6kc-~<;jf{48#HRWxVm@NrcTN zDABr}BY6|-@N-!}@>B>eLI|BpuxM^I>l05>2<*3*hJSHe2M)1t8{(ElWR!=WjaFQ{ zU?+ZprgdgniC!y~lFpr|E)bKCJW9tmEw`T8m6b3liFHXqx}N9cr}Pwg>=x4=qE9&> zEcyx=rKwYXYGboeB7Un1tBB{Qj9fnZQn(Q)?sNG>6$K5x5#YEV8}Zy~#>d~0?WP7> zB)9_QF;!eG+)ooqC?BY05peY(3TirVr3Hj0Zf}h9C-XH>iL&Ds2!jL&)U227gm{~? z-)tcGiMpn$FC!~rQtOpT#z#M=_XO{6frz7LCc1XA_sDg(2 zfg{dQ=n7Hf!{!rLp`f>WCJBtyqUyX7N4J_T=rfS2W)<){BSgVSjt*J*GLjaAk3xvk zs0;FRKtUb;AeO)E+$h#^^W(V6E9Ed0<(cT4x{G2Z2a3Z*loMhh1Qhj|=$$^uw? zZ&bnsWeW`o$eI3#KxQTb*L+Q+AZ~qMXK7Q(lik1VMi(0c$|TZ zPnie-D}`O6@=Q@VR;)_bjgqLOS_#@RMYRYyDqSmDgra%P)|e0y%jJ){jFyGc7$umx z6qPF)t$6*H)MA3_OHr-N(MnQy7WKst#Xm^WZDq=qFPb9Oqa>ELz;Z{>bAEU!UnJE- zd+_8lDMHdkRgQ$Z6-1PGnw3q{(96Qh7vxL61#Pq^>|bbRw%fvon_M1Hw-POH%p%Yd zjHl6xyd|_0`u+vCNH$!*fUavg;E#(kHa3`Ks<}4D)Kk+gfvqBrdaB!%4}^}fzSqFr zCKZK(?w4DJ2GWHNi7Cw#VsTyE@xmg&g+S@Cmc3T(@+le2yrb!2%fv%bs3IazN9zId zUXQwIPry*+_+3<~8Lc?!W}uJ-oO&bfi0Aa8*X*vA#->7Z18vZh1;7cSq~+YgXVCBk z?Vf1}4>_3`^B^S;xvQ+)zh*H#71gNnc2b?7fE`%e4 zFG5jP6@evaUHHH`kEl+h&v^0umuQ&b5fk0TBb3Zkv37dayG@jx;11gQn4hw_8YEYrIt0l*&+SDe#&pv)UcDwLVZq^Z9 zm8Vy~yc)E?k5HOiX5HT-lJT17H;k@sO406E@UC+B)rnp57XT zfFMI`*)SFwjNgEZL}V@;kfmY4;}ydVX^J_!AV6(CBuXxIWR7=%XtZ!*o-0yX@R(O9 zENN(hBIMdOx$GQl0cb(ME>&T)V}-nu0Z&&lGiLPYk)tJeA5&dOT41jus=X1T;{bT* z`|uSd#*E@x6&pmcO>`W7tQ89MiG*=sSEGL2#eHwk`GAMslp(5=EGeP;4Uv`H zBE9x2VU#MUAX+bDH);R66BaZN6PnBKS=Zwm^){HyJlRaVrbL$0e#2ILR|+ay;_J`L z+*!8gfKaPRjhZ&W;Re~J)`QGVTbFYhMu>oNhbLs(IvXa^mKj>YdF0>a&?2RwDr&pk zq&ap{*;I{l0mEB>VhWp|($$EA&csj%HYe{HTesS}_}9{9xv+05=5&xec(dZ#903#4 zZ>{iDDDCUn`m z$f(k#;VR+s1yjn8|Cr>Ji%z1@2v2%eSFzBoDQ2m!IbB7>XSUD9dnpve$_v9O46ye_ zO-$q4yISjuGBa$w!Pflaoy0MG3CD$IeQuKv7lC&a2zVS0GxQ!ltj)O&!6dz-R=zxe zcNl26d2iGKjZ*7T?E^Quz zfMx-wk!aGdqwpj==t`}wrWEi6p#p#JUq74Ni1+>7M)DM+ zF>`S+7L$i`p{$HMrw(Y4o;{)GDhKES9tn0ef{C%I%_>5s^#_!xB^g7G&<3D9DFs=_ zRRraMu=D{r_)?ja2SZh=VvWshbrdU?qL!)?vJS$(t({GaS_=(0CV*>@GU0@)BR*Xb zBwfqGiPNdPj%kEMT{%kS!BAB-EI#sO(buhNbxG{CDGwhFOjee&jXc+|<$)4mGw2(x zGxL+>OQKQgbqXveUtob)D+QpJSM&u)qYNZh`^vv0`Hrt;O|47?TP5Mc#EVprOc?KJ zh*F7lPH~TqZMyee)S@Y&uySm8_y#jca_sUoiwoU_?)F5iJ@-QTgie^kcr|&s1m=Xx zbT*M@64SRFFT^T^&m*UH+aR7Y^4)6j^;^Pp}v#Zd_|l&?c@B2iduh!ivQX z-giFUav?{Lcw%*EeJKQ`ipfArVzIVPimUT)2gXoKOu$)_*6D$EEfJed3(*}ludX#4pd2*;aDfe$E=Po* zg}@25kvV(~L@CxC5e0sE`_0IHF5R)0Pr?C$@le^jLxW*$`94?i5JU}r(GR>774PIJfA&TRfZ|{M> z#45f>RXJF~BTytMi6hE-7)A>dfpoBpD+Wv*El46OJ*Vg@X01j<=A)J_RKQsV+md^w z)^u#sh6KYu8U(H%Bk+SP^uy~ zT=YkwO4qSi#+OdOExuADMy@SzU0{W^Uq-ZU*(_C%w;k=&#S{^swCW=Oa2myl2*#_6 zsqA@mB+M=(KG};NLJw6R6rDF@`Eq5T zW<5V=QNif4z0=O zwzJzhmo(AmlvJcBLL6K&P%t}sY8%rl)uitN#q~(KKw_I^ZZJ1(+wbgmYaNxg zPOGru!dTly;+h|Wmvkjn=M;!GEZ+3lb33A8f}YBjM;A~6NXsxh_9avTzMs|H z)Z(f~!HS5Fc`~M#XFY!@zC0Ba?QljEmnxLW?@A#Jz7U~VE?S}`Yug264 z;cRyMV5t*8SUHtb`(eVK_iMPl56c2 z2S;tG6Qh_+4F@Im_jOAER1G*(v7L=YraoU%O-qUP#fn|jrgQ24?BmHWmGL2%V<)T zV17@1*c_9-rqjig)nxZdmR8PAx#fjx1u4>Qlh|XKO2W-1-?YuTu2n2I?zy;$A2e-5 zJG4!?Oa$SdX|XFwO!Bksw+pqo(3aeu4>@tY^st5MH9d6oT3UkQ4Lux0jooCz)$W~* z#VP2tFRgb#S_&;~9X-7SqPDD=2_p7tJ1_pyLJinfTNj>>DTDkNk+D|z!XwT&U0kSN zQfRQ=?ICb#xkm#L3@JgV7@t@Z3Vr;{pq5xmeKaXu8|I5wi5Np2ReL?MK5kffRU9io z8-Rs+L${J>M*}b-^3$YgYFSf%4#?NarTW14mxNv2q^891|u)$jB*X{Y< zWb;(cb}iwhkIg!vmgv_U1s_YLEhd*x8S?P|6i}_@(R?iyOXX}iMNO8XjEA%GLj~z! zN8lePba@E&{53X`{KdSLn5u643uS4lJCi^;QBPCP2~4N1XBZ-N71#qwND>UtY6fmA zg5wIKf~u^|M6id;k#cyr-w5?0)mz#1!WzzWsbu3kP@9&K3|vksc?N$|YiFUOXpJdp z%etmk+9bg>C%-0DO4gZcSiJSNxX?j6-s}RjPu$h7Cf9;w#>QliA0MG>?QBJexR$k2 zjH)DMI-#SsTD2i??UL8HseJ>Ht$Ago2@=G!^`9oM<;ie`(AWV2Bb*;U94@_Ow@Ow+ z=Qw;i<{=S$s!}$oc!m75Ryx%+-_$s93)-(spMaUsnGYMY>B|~s6zTYZx%^bkA@tgS zxs~FRuU(3-sHo+HJg)=BB1NcFkt~9z{Hxj|0%ky{I-_c2J92~Mc{x@4DW_hk3X@E%p{od<@GQB{2lnIEe=sk^+t%0>;kU6(Z9f z8clD!s%entwH5s%p~&%5Wo(dowEdoyMSFp2sAG}H%n)xFg}Uk?DJ8P5tJsE5Uv^9s zho#sKG{-oc?^Ps?L-uA;P8$cOqR#i~i8|&Ta;K8agkFN5!#~<#93_JhH9Alh5uO9r zYa-mAuPwB+Tb6lg(>r*PBG(w!lFhZkX%|^WT-`ASJ_utqZ(LkSdLJV?FFs?K!N1h*b8$VtI5GT^^4(o+;y2U0r zHj%%ArxwVJmn3u}>@#1cr?X9bi3o@PTvn zq4mAh0$E5*u3GCMzaW%s%R^1ghf3Dd)J*8S0+xzWF5YTBC}o7^e>mrn4yBapQR*g) z1$V5F4`HEV+MCx-Jo%C)-*;f6$4w86^eE)kFR>X(_g!(4E-kisg;C&pmS`&zJQKBR ztP~Vd%x-7Z%DS$ZKzp$xEXs$9>M+f9Trx?0($tC<95gox-#|{)#Q`YtMi9oPvrpB)C$%tQxOc}4!i=I?S

+0)ae{JuImyYo(En^wCq74==ml)C`D%5Sb8Rh&=ZC`cGYOw{!Dq@$ zcdkqW7ppuvK0-X$LDv^Ufwd-ZS&Z#)q$EDeMfJ!)t8I>dhT!qf4=n%bf&cHH9XQ3T zCVoj)ztkmK;_O!7_uo`Y8;5+CI0{tD2@y?f4V4)0CV7sh@S3TS{cQiD<#_~il43rc z=vfbX{+sC1KG0=}nTK&@3_D&U)NzR?2fr=GOfR30a$Jx9f1l?#5bsPI0$##TavY6W zWP-`Q;(ynnGG4y&cNK}XLJ;f7gx*A-6xC-b;z^2$$Lfyh>By7qM34H=<2DjsqH4Jzg5S<%S->wIs!#aKQ~o|A zwWI+&_9yYecc>+D3~(+PJ5$H5_Mp2qOh+x9PIO6DT@I4C6EyBlB(6#t*EV2_t#vl9 zit!|@I|$zm!1u?betvTq!*2_DM_h8M}6u&o)>>cu5L)$uln# zUgDJ(oMietZi_*D)(F2HqMXV9L!XC#5wD!>^~6w0>ikUj_df)aoHdm-=+lJnhT!{l z&zPGC7ZubalMzp>#x`C#PC4M|w-xlT$9lp=c=xi=oR!a*Fy=we{udHliHhrS&%Qqr zuI!y=3q3J?On7Vr9-s4!c{RbCpm>|AXDolhiENF*Ov1V0IzGBym9ygEOiKS_& zxK0Xs3;&VzkZfUnTxZ_)?0c4v3(tO&bW9tMt%=jLE*}6NF5k%d^d;oD;I;e8cbRX_ zj9Y_xZpgd6h{%M#$)=&0$K<4IR6zjqG%5e$Lo+qD;mm!QY7!EDkjT8_%{Yuo4Nq){oepUuou72|n>q8zqt4J(z6;N{YZBjdD!sU;8`khC-)C^v_k#O4r z5nN1a-&d%8qri`>-R)-YGZP2OXS59tK23fMK0`jv9F63s^~Q-fQW=g8p7mh=7vThV z{|1~)jOb+hP78E0=0)@!J;o5S25 z5dZS0HHqs@6q$T{f%3 zI{cjaOZhoM{3e?mt#>6{)>SSyIrxx$S1KQiB79meR|PKlwBvk?{ZE`sRbNWK7PtId z3SXL5Zob-plj}TMd`0Tu*QkRX9%6ZrZuX+j*f}KRT0VC?eC9+A#3QfU&93c*OHp`r zgb%xal|UzBo+Q3*0bgJ4(eSoNtX4z0uCPxrTTFIsk%9Atb@9t_MB@_GxS_^mxwm~+ z4%S3#%mpN-;vlB_<_6-CvcMxV%|XR(`?omLF}JQGHEABS?-=opeb0?OjuO6W6MwXY zKNgd?>uB6P|3S;&NsYP*ch|@>Fzz97F9_l`<~qV#k$NHFyz*YNxpQOCeld)y)pRe=z=aD?HoJh>mB79j)OW>0?h*mh#!Pk6KErQFAdrg4L zn7M?rIYAW-Yx|Eec^K{=qKi{ao*;gx9QYy2bQ|qHZv6%|YZ1ox)txINyji^(sn>t= z@b)R;W^%yI0&^azm!)vRRHAizXx)-K2Nn?MK}-hKjb{=GxxEc_~8in zj?EwIhi15P^=8E1cI+I@%_m7+nvc44lz2ZKd}RWUYyL=84;&+0PYAePY`TLp7v^l7 z%{)88hpmUDc+cd?@Zm}v12wLavV1Jo#TB@8jC)kn#YukVlGvVXe-e>aolU2EjsK=2$JkKIpdR53Jiy(Y&`7n1qlTg(UTJf5o&(cR7k zGH**;OE_Gkb-6pyJwbK?UU8uW_j zYcZ!O=A8ud4T||Z;?*|r>QWC^tx5izi2SKWVwJN+lGCd_{oX|I?p3_sdw6;bIU;#0 zo2`HH^M8>e#qdTWwD*WNI>Q^|374tLWnU8WLd1L)Vv4OrHqR1*`q|7Zi}6ORj`7g2 z8R1JRrSKK^tGgaeR=;n=-`q!d+oQZ);Ng58i91E(eq8$&E<=BX5e(D5$0{%Ob@?va zBJi?3!i)81yv{2*h|N{=q>gq6FIG?4&(>ji{)OE2DF1#y>f-m%{9fYiw(xd7#*JM= zTfZzZXW&_7>r7GP_2b9(@~ps3=4Hb7^~%W#a2gwzowu6d3ApjC!#N;i5kctI1$*pK zzU<%I*TTD*>zY%ER>`W>P~xQ_>ZKYnUJA94%8BP8!At3ZpKzX<=si?p>-DgE?v!`F zoK5g0DZVL0)4?&Cenz;xPRDPp+F1VV_g0GkQR2BwoCB$YSm#GLvbj147{pbzi9TJS zPgjf`tE(Mb{Q5KDt%Ks;9`S_TSLXM_k^Hp!7n>8z=fubD;Nw0XJiCY%6;zADG4A7o zACNn*D2ISnF6R@J!&4(1N-W}}f$FoQ^UK#m`}(!Y#YhkC_sH1sI`&;8u0)NiJJGKj zl$+!kw~}Ix#@tphpG#sMpfT?y^TWxggWr&t;xwjG;IeDZkgG5+8^Y6#)z^=cxDzz) z+5~@l#s8~f2$c$tU1StFHz;QZuhQJKvxtU0py5E`@mh}LDn& za4*rNCr~_&K4aHr$Jburb(J+F?)e(`&xG^d%K7*R=b^rGJv>|=6wGly4{jMaFGKsB z)Qpo*GnT!#rzP7dAG(qoA6oyUbB8H&#OKEoCIF& zeHn7@aXT=$bj`%7V^f-2^9nfr`i=0}2fZC8xOXY;sf5p!;IlvBth;j7`JfxqLge;a zI<9CSOj{ir>bSMQN$i|%HA@b>HqES2KCOoK^$h&tXOcU=Aa_nC@tlfy?j{;9h${*1 zC9Blt_`1lBC*$`6k0&S>_V@B#{4+AzpQ{z2CyxA4rJfCckT=Mg2;OYmWUjvQj#Yn$){}Soo0{43D zD&2PlxQv}Y?Y?r3Vo)R|J2%7!z6h^ft@7;OOf|H93LM$`W5m;lpS!At{~`XEul~3L zIz>Gz9;k_@HZ;fgY>ivSlku(RYiZoQ2(|&hR^fK{@ntvo;|=10WO!f>;miE(0b@Fj zb@%-%@}(xx>Pp4@J>euyIeDDqsqnFbcjUx{;4{jV z#QrDvl=Dm95k7K*zT?br!bdgbqZYKtK|i*R6yRNW!slFQksjRl*%&i>bJGe>W0Cg` zcEwe@?pRIqGQIJ6;Qdf<(3l8l=0|EvfM9Lc&W`<)spdJ6rqitM~vT*z8(Q zJkuB+k6lC0f;)$W??JUB{<;uxl%4w9dS;}b(5^u3$ zo*v=U`e}~VuiJc-Oq6?L+Y!z(b^L84zU>-ceWJ%Y z=zwK+BeRk48H@W2=REh4^h4*qlk~M;g=|0qicmn}hG45OW&7TOZob)%Xc~ z;tZ;;1LR0BJkxaRKX6!&=+{B@8%s1wRvzylJYK3i_JXgZme^wk{1|NO;Vbz%3tYNl zl^XmfVwE~=H(Lk8wN7}aO>=_3z2biW_+rmn+UMA0*0uQ4)J1=a`==NW2s_9uKiyA{G!!9Jiiz|kH_lXGs26l;qAbSTyuL) z;}LGdS`<2JlE$+Od{ooduEE}x+3%B&fV)`FT5rpJf!-wQ{tb)Q<|P&ohWKc0Q6iDREBMIPHw|YYb+*Z0s5$8&9Zg zg#T9@=f2jM01x#>Jhm2xvC0U>yn%V=Q#8@K5%K3pxML}av6aTSnfPE6eDJdBY<0B$ zdosuiz*SmI{&w{w7no9__GlA_VlFz-7&ui;kmgrr2a2O{U1m?HVPiAPH?wS+}mPs3m!YRe3JQi{Qn2S z%VWyRf{0IS-TxrKzQ#O3G)qv;c3}M2I%)Tp@#_=pqZRw_1lyyEZI{Mod6n;yp)*yJ zQwa7qfnC;9ebg^@f8j^A6!@hXu(@!{e3$TL`C~;p?jgl>dPHwqqhH0i^8O7udbx#Q zpP|_QLwJo>UNZ=WM-;`?G6XNTW9Vk{7qN>3JE_4m7jqTeXR#1*MB73$0_%h6MaXk zujGnfT{8Z|I{r!Up44C2j^_lf55s%4(Vj(ovHr98hU4!ic(7j!Y_a> zc}?dctw2Elw6D^0RmTky5sTgM#iT(Z{_6+lu2Y=e`|MiIE&1B`} zRx*!d!GG@&e+^cDZ6`4e)|j3qdX595&4>@qfe&_*eg|p4O9>zMsTZ~q{|$iuY7jmq zDIYgRd}4K%+B$-0lm?A{@@Q}}eB$y@CHUel&v?f?eV#=)xK}wiOmxkLt_jD&V*{JB zHpaftwZCdx&QU9r`>O z;n~J6$5J`qBX-`ge8}9;gTy*PW4(`fZ6Lh%0>*S*x9ATZ1}GPWp0U3s8s&7lv3-xm17`?kP|JvS$>$uYKY(n~p+jbpGgN!(2| z?t4jW4K=oYkul`liHy+3}PqK@LSui0}DB{=sx24_gR5kC%rAD_G&?B1 z+t1pQ>-gc-lkn`bTss*7B#k3DEe9odKG+!SKgr8cp4kizqa4#9_rIDHrw_^_QhpNzi}qn`Tr_z#*l2&eUx(+km$%kNd< zLgngYy4RA0$k7g-*yhIYC+@MeqlbEUJ(-X4QM2}u{Hd$?lLc;EYw|*LUB~Si z!EBvf0xfqEF7lL%&j^?G0xs*Dgn4eRE`~q*MaGTw!E%DR8!*fDjUk?WZvYIfmkB1_U$3*bPa(sJaO#7PDj!gt_XT^Ib(dW;g z3gdZto_v}X!E~JePUd_vZWkT5CCNp(lGPHphmjnqj2x*+JaGv;agfCGy~cA1aK&nC zxsr8c=G9?+z>no>bcyP-0P))67x^1ohbx&GsE9LAiA&A9B+se@dA7tHBXh{9m_zoH z{4GHKUgg2vTXR=1$!22`9+yTi+j;LAATB}Omb%P@l z{{J2^Wr{g;v(Igb$9gIe*^!FsT8t;SG{M>=d@AU4JRxfVp4)9Eb@^3bimgMocFOtU zM~Ih)!^=04Sf^^Nsh%;{6COpWmcX=-cxpR5^{xl+Si(_F<*3i2?m7H))V#k)&8s5E zTAo<$B|J<~9=;%&H&@MP5X?0c^9{tS#qjFs;3)%q$!6b2DnDNio~}Z>8tr zy94cRwEq%J%@k8dkC$qCxVVhy+EjHt8qvIRHO?W&(d93Fd_hiChb>*-(;z`FC z_P)2j$HiQji&hCOAFU9r2n|3&ebHA zY8uPPh&DD~<=S&653YB~xRZ3;EX6JU5q>Q0riyzk#Dw-7$7DxY5yUM4CpZ;||~g8X|l60hZ~ zdJu0LQ=8y!thhIkdb9>^Jt?BI_3RSxIl>d~7|&~!?sRiJ5}v+_@Ki;4YD8kGqOnZy zj9cc3#e7{pU#w>)DE}vT`h5xf$F76znz9M_Pe;S8q~<~5xhvth>F7JU?i25RW5N}6 z8xnIPjrm5xS+R09jCi^lJiS))$>y)sHy!mSGpIqvbRpx{*YV$r)LZMn#_GSrB=%j1 zeUT$}$e1|V2=C9NjGl7e(7u%DV#%fGYk$Sfl z*?I{X_e&i&d%*Ge$9h8iS~VuukCC{qMcf~gxC=Dyon-tkbo?bmk7CuM4~cz@#{K~O z60J3YeDb?q*zz^D`NYSg;p3Y~+@EXQb-;VZcXui9KTnD|)HRW+zTzSgL7T}Kcafll4 z8wU271oNl>b4h#$!ijt?jLbU!f!1=q!1ih1E0Kb_9`iSbj7F^j}eN#nSJ z@L#C>Hz6GD1xNQ0?rVYjrG$f#s@nzdl=vd7y7)o2G4Rw_v>C+D)#2wVB&LcQ(-FeS zC(6kX!hezSe{+Nr>)C>UlkVo{h(7k%Dd}&0jz1-6J>g-5@=)!R}qs`Emk(=E{HJ%YWGV!vCl%XqTc^<@dJuAPSe ze-hc>){lzVU#{7lKw`_(*ftYx^Of8C33o%3yHiPQw5B&(j!2 z^3iBMb|mq=tMP3h{G=&A?+^`l1=ktgO4vs+;59bit)GO`!zAupjr%i_54DgFP06^)8Z%DNIL9r)xLZkm z+KBoz#lbapG5=An_Yf{ql*?8TTy|ba3UEy`$sSy%6AzA854IFWkBlAG4!N!z){Xsymt^Iok|*vDi4Str2a`!&*B4$KxFv7jQrvwB z?gYjC3gP4cI2lCtjn{o^cw%~t@R6i^bRs!55jiy?GOqPdTrlo*v(1xJs|g=(Dj&Z_ zxVAcG2VCPbv@o{htIbpKzHD_cc0*6Rm9pK>9;l66t%G)^1DEvshT{5$=x{G|xG|C! zmXC2kUaU9mJh(0<mL%hE!CczoY$9=%`KG7FeHR0m0axsf|auPf_(1U3e;qU}-c#C69$pM%Z@!p>uuoz_i_6J(El1zlNw;(86Heq2v<|U zRm!#Qxl(w@!fUa|IyMK!20V>0A9#GR(1YhGqR(@xPcOn@M!;b^(}HmHAUHaY_-Qiy zw9=-W9zraK(4Ihh z2JJA~1`qzc$KCk;h1`CR@co+d-87=J^<;v^{xb1h6T~n@wX(TnJ<=%9s*O3 zToU`Miffx^->kpfzLhoJQ$&wx(4#xiIbLJE(lh4$#9Jr8ThoXq4??#x!cha|=vvR1 zg9%sc)@#@XUq?YZquRL znUR`ceJ1A{<=l22c!)i>ZO@&4i#y=t&Z}a)^H+{nXW;+$doZ*_+_C-0IdYjhMjCIVaP*32%Cq9O22A%!}RY+gaeYi-QC4+e^y9E~44v(Cls!XNt!8xd-n| z58kbW_jb6eYbfx#j;#}c`F4W!DPZkPIByQl>l1!vgP+YL7d9go79$3E|An1<b2ZWS1=aR458gT+jwG9zy%aXh1Od`3K7OZmGm z(znewSyNt3`hHsbE{V-?2#+-b9^=dl9v;i!QM;C~{EB|l;n5S(CVO~l9pN~vOLAQ#%#Vi& z?k5y?)^+Y<2C1R%doVvi`pwjScMzWEf#-#uct6YHg0Hn zMBlD;l+^im5O3_hfAfJEk&LpmC8rKgbu17V3?H=4GdT{M08qS7>9}&z$6muT< zaK$TLex7J}A~gJ+#BxYuS>nO_1;I2}F`Yy5pc(Suzma`y{tXKDHRc8nhr@_IRaKuF z>J9OfZ1y^TI{IFMJJe3|#FW;_eZ2pO^3k2-{RPPT2E>zt)sverZfs4lzKhp6>=-zS z)lgoSO>mz~>c$b&jX$xU>lwYWLJB`IXd^xW^a*po!|8OwX%*$Pi12bydHITX>?C-s z2HE#v-M5p2H;H>EuEXQZtI3#LK3}a@1_oX^*}O;cW)AY^4&uS)@Zc#V=HejcOYs>3 z|2wYWx-!5u)4b^6vk8g$A&t2hF~w?T&!>c%9e<+Uo*2)_*w)J}aRes!tPBB0IiF%{ zXE;mYc@DsMDcW|l9Rc2VlF~16A15z_M(YU|MXEnOZJ?Yt?Ko0jI+9o)R8+VBLkx|G zz5@b%aj&dr>`x;a*qo8~;!pAHHv_N5&H*-_ivq52emDkm=(q4M@N{K-8Pk?v?ys2N zBED+@-wg&|F74$kT7A}&R#Kp&t9b5HI8HS5+8f1Isx&n9u-uW_e&u-^`CV(YxcBJ1R< z$o#Sev%sB1)51X0&SpGfi|yCug2Z(u;)%W2$<~WA5l?t;@<#I~@oXD-wkOePF?7oF z#QG`GqBgXc0=%)9Y;Efmcteitjag23zE62>OLAZ?a^N80t3Y#LE77=AHLf0s%kn9; zrIh%(Yk(d1mXQ2<4f(Yr;$7RX9AnpujA^}50xl*J4NiduXAz$6Ri0iZT;wYk%{}8T zN32p0>}H>vKNWM3cxz?MDkEXAJNN29?;9d<+t_3d*+TFiQ2gs6-nRRmjD0(Mu-(llg?`l&3n~>xrjnuKSp@ zE%JAOhogh&GXr4l`xUGocVqQ+4cbj;H>2Hxb}QQLXiLy%HKMgVZ|A~);NT|0;oZvN zlb$#)N8eI6>}KEJJ5?*Va6HBn@9%`;O3Lx`p0TgN*fMw9T4lMafIPsRaX3RR^V%A7 zF41@?G(O_#|5W11`S9d@gtPt1S$m>KUFcEj;p1%&o_Z&_J@qE?;11Qna$)sI1Ov%v zsc1RZyU(*URIWe7*wO2O(oe^~=Oz1|nJVTlGB<9;+<2I9bC+^6mE=Y{_;@9_ajmoF z>pE*M(Q+BI{891S*zL2ir7kWhR~f%g9!2!22YsFfm##I79Q)M+hq3dzt$iaf=rN2R z#V%MX>m0V5_-O(B)P!hLKhP%5d_Xw8Q#sx2@zkp%o(#k@0-kbVeg@SMYcF%Lr{713 z7G=<)tHvYo3rFFXeEwc|9p`5f&m9`iBBD=y=rc+4K>C)==DpOK-5$JO5FRqY!*oxd zTZmuV!>?81%CGaRA7mbVgYdH){LGJxXZI7%pM+0D6B`$P47QWtlZ9w?Fs4hhgurK& zOj>7m4((HJ#}KbIP;C}Ruvr|!?;YSbI<_1K&DQ)pi|AGvvszORSCt6n+ZFS2V2X|_ zq#RP8CY<2T*(_-LHPK-ubXez!_0fozEDt64)Rc~hC3fzy`W-{1`4i0qS~N5@NnE#S zTnk8^7J)9#N5z=@Nuj1aTEL#)mi+NX|! zJh65o+T=i+g+$jMRM-8HF|8M+UgqE9&i%#k@OZ+*P0GUy#BUkOj?v}yNx&t~m+fJCn)e8&>B?#5kn-zt z%b7gY@Fb$u>Coy|#3Vkjn>~IKt~X(ZtcZSHK1mC-LL3W2@7n!s&PZMANBEwoe1Az| zO4FET691k8|6WbB+M`+>1m~{f6qzI2k$mffd>cV9Pf*NRk$5f7!qL1G%|pvaD?n?Ye9P;hPeMjh0=_>Rc-RxyAB4|T<@0XB+4YL5FcMp=mM0Ki z#w#ziBKyYja*&LBosRo9$&da)ek?Kb$=Ks`?Cd?|uVse3$#sqJSnG14i+mExnZ#pD z;IT%Lm}2?(#G^y+NG{s_Wc_x4)UQHlUq<2_t8uVYc=?vaYSFoN6WcAo$@KDXY3?JvUh zZsmHmXW!R|{u`kGUV?dqV!o8jFI|ymBMBcBl#gGC4n@%6j7T0@ze-(MVC#w>h-c1#XSNfL;=xhQ6!-C46=;5@2TSjWF1Gd#3XVzEn!|*Lp~^#J z!oyX{!?~WZR}c*nRD-RaeGifR=!X1gLoi*bnEoA!$=0zUh)LGUX_vas%WQ-OmwPZZ zPz}Vmu|BR24fYf55}@5j5j?g&4OWiL0k^hg@c6YJJm-R6m(NB3-?WGat?qKowh!U& z3gz!Bf_ISOT|?%dOTq3%MDuvn{1#6+GuZ6+;2J~t+M#^)BDq-;zPQiR?+e5;iSW#y6l-0xETXOTq8ztOBUmq2 ztb2(*ajH)Z!t+Y-{9lrj-I0@rJaIl1dCl@J>%a8xnI?5jC*p@Q;fIYx^S7Y&+i33u zn%6K*NIa_$&m^K-E$Ft{!|^GE(qLx+l7RWBjDjRv^N4iM#sJF8KbrbTQ|bvY2fh;!pCLG$HzLR#SYlPmWOi(6NtuV zLF2|AJbw_5i*OC4jObb$x?TsK{k=)+Z6kk1bc~MUrsbW z8ycTSw5kKGhIsJS9O^#jlww-rE6zL-(b;p^^xtZ`P_ z>pl;Jt7iDZIed}_8^G_$5soasQoCOyJY1wad=1R5dsGj=i}#@&LVGOmB|a0H_^S{6 zbtB>P9Pl}u#Ga(FukqmDuHHKC3}M@tjfne9w8x1D>cRs@5nJr}VSD~kK6iT+^r{EW z#g~?^pkw^g9<{nV@q18x zhLKt9cVO?k(C$Wi0PP{PgJ?_ex6?_EB`W`q5be%`c9(dtj3yivfuk(oWI2B)@$x3< zd6aOwRk{6`=v@zb@AhErr}<_13jKs<$C#1$GNurCh0)m8@n17kIb23KOi&KDYHr9r zwh#HaFLL8`!teRu_i^Iy&ER4O+5*CHF*xq}w7VwnfJ1Hp7qQ;A*G6QX7zbQqNxjKb zJ~F$y&#P=v9sVLZ)Q1kuJlfyq(Wo`{%LF#-ZJQfApuv@BJJGH~+kwgKJlv091?Ga#``wW;T&jiIohKh+}{&@FMz%s5tA!l&jI%H(9TD@0BsA}g=kC6 zfp^vs&8r~RIz*QXRF`KwID2|@DI@%(D?bCVuj^QL6A+(?c6NaMi{$Hw4soi(YaVBfyROBnhwQE3cWCxzEjPfyQSL z?$QG8TAFt~F~36Q)c&X&TS>pEs>wHzevhvO>zZ2#AJxFe5EAQo8tWmVp-~Mp?>$~C zEtgX3&Vvq@q0I;1vZk;#$IiQ}!L>Y(W_`eUn7Q4E<_)2FeZu)xaK4*xlcL=-e&mAbJJo_?MVR2)9Y6YYYLzxxIjBw^_A24gM7VY@hfs*c!v1P0-qVxW84ov-{Y3BUNUd*=**KxMyhG8N=Mi z>IEA2uY~)WhB?_-F~ z))^Vw){cC95+!CC%pz-)tsj$*6223Z?~04v^`#crK80wx6*^vwHo=4Ob249CiTUCs zg1-*1hv>zpqBfq{Oti{Vt)_c0Y>9AeYtXcS<6`qL(fKS@_7*Znw1l=9H@MGB#4E4! zJh-+;aM`*uRki;>bHIAm)_?)JK4?rds}0W1fo87x{X*!~hj3X*xxAX-nxeSMA~9K9 zCCI#22$yFnmp72UPtd-lQZw=m$5L^=!*AQ^#%EJy= zXYY;RiH$d@Tlsa9U=_b?RIb(&u5*;@+ezOgc=GYP#0%qrIRkA7&Zv$ypC&f}r?G1{ z%U37mv;Q;hIpZqS_Io4a+kJ)Wm4xfM;Cc_quffQ#FM&IDon`yXLZ3y1uQQadq-pMT zR2yj67VVG+Zx`_3s!46YLp!t%0Uy66pQQO=amjblEWwPzmoZ0)SH`JVK8TrT@#n$b zvVW>sjW2wLtq0={;)iVY!+C`Bdf@zJPrqLiOeu;fetTHgEM8mJX5ox~7TR*WFeu_9 z>+@CtZ);3TqTL47?le+&;+5AL(AJe>?VxKa!FPQOzFP@*S<2lngoEUOgHrRJhre8m zAI%}rbgXKgaNqytn7p18^gY3R<>`ACsd>%7Ym0ze9Iq4Z;sWl{%s|5ZdgcBQ;U-hL z=}5S55AJU!o~sYf{osi!3!J#}Tymfe_;kG{HK1aIOYxa-Spi&@qBSB~j8QGVM(uGO zYYjo|8H#p2;Sx_34)VKNWPF?diGh|lhWpWtU25W~BuAPAI<7S{h)(NNr&ozi8LHDG zM2iN{VkFV912pUqlRtn7E-m}%V67NO@Wyl^ypC308xUR+0$v)KtH?aE8}mrEhqL|A z!iq+WFHPg?LU6~a7i)WPUry>uRd7-g@M6pYGM{#YXF8!x(D=kNve|PF;+f(2|CuDd zH5y+(g5N0qmo*oob8T&`Tt=h+W}f)WaQAtQRORj)qFW>AHiPIkOm$mLa;Y;o89`!t z2Gyw)nA>?U-vUis*GUSXM`g5PwCZRz(Q2bDF=r*dL+Vvcr{`Yk;t5lYafYfX&V)3_Y}69>P_@QNs~xT$cQ75{kV@Y~^}*G^emI64h@+9wxC+-W-@U#ZhFW|D@z3e%pUH&lrFY-C%fZr4FCO1G_9eU zmJr>NRkwYFx7EtqCgSgr>hHtEhZVp}3R)Uk7FrHkMKn3jRz~7|QsbTM@%=RX(UgFBTug;ej1^E+CpM} zTw`A8!TcK0;#Ae5BhjKMw7ALRkKu%iMCIZNg84DUywQWXF*I`3T$!`}fInR8nPhn5 z9uMB@2%bk3&-oraZHQ;8sb{_-9IsN2XA!Ovl&d%48<*$1!#6$9ZX?(aDfVq1>=TH- z&7kiy9=<*zUhWAzJ29TCu6GUUx-q{KK2|CpFM7s(fW-QU^*Z4)KHxIW3?^DtRjnQ) z{U6l+zbA3`M%>$w!!DghAcseyrFD1nvO?qT@vM8!x(2oQT@NSE5zG%O=G%!LgW_bK zeITx01$WM*BWM0a_>5C;E+PJD4*yIgTvt)9j{vtTk4urq1%#{R%2m>IH|D<3;Vr_) zL(0dG9xk8sUH;63&besum-Dsk4+Pr-%4uq3-{Wh+isl{g68qUC^4u+1=MIGb z3K3&jzW$#CLGiXIDoV6=bpPxy$lF{ujA$C7VvTb z;)~_hYFiE>o=5nFexS4U$7xSiDCYvI)K>Mc8#Jsw{i+#!h1^YZk265(=* za#@kY+fn0fN@6;oe11%7QvouoEdZZGd{7BKn2fk$uWQ+RBQv0+JU3MC8(xXewZ1q0oYM>%^2 zeY9S&GNx=c2I0F2;;I<@HvFfmsT%ws*N)_-RCu0hq9>Lsh=wPthG%ZQM8D%s>wQ?nV;ZVvTLS zhnJ(CyxKr(YmRBC@kX^s)p(CZw6ghJ2(8l5mU=K9CN-)Mp8Jy216+|Z+cY(&;iSU*Z@K$6t zVeII=4T3ijpQ$hntrX|_7HORF``9r$pi;^@>Tbm8%4w;E=aT*t(6@XNWU0A4zQrkS zueL_+KCE7qv1POOYlRGMG)D+O3-vE&kvtfSJh+%(ivzA1n14!v@U%$mHW%9K{5YKC zVZQpZc0?b$f4P93uOHHfk%zmL&i^v z8UI!7Lt>N7et%o%!`6g@Jmug5!f`w0cn0A(PdVO4Fjk1c_%x|$**F5p1?FD~PbVr* zpEzQaXln#DbFR4;7-H+O&Ed)chElVe#MoA2d@vG&^?4fhmplej{{=DquOzi1S$VFRv#am7jMB{-VF}<8z;h z2CdcSIf~K7XE_e*`4aO>Bz~)LE{+Czz<;h|)f({LvB-WlcH!-F;C9VVvgW*+a9Tk* zZAv(qr<@c-;<0&a=cj7_@cMt1Q_F|FMnCoMtT*N~qFb)&_7>s1m2zI^A22*ca&A0w zE^~+b+>G$LiQvjnT*nZb)I_^kZfrek_z$>x^>F)fu5#bvANK!(@X}IwNqV3>KI_G> z+RmDUML5e)&enP`mwM{hRSoa?~2OvF^uibi}Q%~1- zm9O-Se}s6lF+6#_$8!~KcKahmIhjc~X%uj>A$cqDK&pD+VWQZmKM%{8&7Luf2#?7Dk0s_o(swwQ&NV9t z&kfakZI`(7v_10wA`hE0+cf3vOHaQC32$=( zN6avLpqa%jIt#C|_OGv+jls_~l0)3q2l!R6wS~wf` zC($k&+7+QsR~?eiw3B=b>(Cn0jPN-{`5Xvex^!+0U$#g4))UvOgwMLlXANMKzU^k~ zO^6WhW4wZ&PgtYgv|QOf;=%U3cxmuC_+1wMJNx83aLzonxF3on8&)b9J_a|s6t;NSt`jU0HR z4aRWgruc0RsY7j{b;g6`_p|<&Bd$&nE$zH$tNXje$1@Po`sd&qp#8NTR>Hq(RcLc;$9 z<$pb}xoWFmlRJpyy3k5I5%F|$H2Fl&IA@|C-@LWRv+pEN?0KWy_i5zgo|tyfvjzMo zb=zu;AA@Z+y!Sb@cFkGqFsI1+^8AQTV*Rz;gEwiZd(6(LpR*&e*gj=G7!vV`V2%Th z8i7x;%%u@LHYV}yTHtZ~UQwxau6ESuAg< zLF{$S?VkR}lf0ROyt&J>-!sHVlBS?r>F1dJeUp; z&nBp6HCozNM<~C&V9P)gP;f?@Hmj8$B`2Bzz<*A8&bL9!KhR7u4(ho-r$? zgll{2QK?U|^@cu+37#ay^Qi|i@QlY#Tri@iD$INGmzAbJCXUHc`!{=4Xn0d{lq-08oU;XHFh4q zAi|T~HxWF^nxrl9O@H|2-=2QcW|gl+(c{HOBV5^d_H+Igj$MLy17bwSP zbFqs1$-~J95p0$lsm*s2-<$~F9P{+~nWxWPgvSKsu_@7hlxn{m8pa;8TaEA}d{Y@* z#=d4_k+sxHqWv1xKH*A!j^#*11FL=Iz^|_-)%J}0vxkdx&zPf#p9aEDw-XNImBZbn z_H{+=`-sF+sJVAGsZ$G-r)H5@E&q%0q^1H-Jc$qa);8g_@P0)5k*fWJB9s?0&Ka?&9flyJx==a3O09+n4oBd@$#xnH&$EDjOIeNH@z}qUd>`g{tps@7=Y;L`6RDgt;zxP<*cZ{rjxC(QB7EC1!e+>~I>0OkXP{~^l%b?{PNkPGr|q~lvM zyp)1=7<0f2XcgfBJY5`nodJH%z;mI_z&qg1Kn`t0c5lS*H{ti2@T8kfcwgKmbAbo% zMV{Bzfg@K949{IPG;@e2Dyk<&lU!beT)qtB#@0s5@m_r|)+UcW1-H6$a)#=2u4msR z1aq!peu-!_ST!0*^v#662T3hRg?8rE~YCNcMyHWVLLtJ z7QW!ddpGLHwVwUXC3v$H?;g*-tq_ZyQ$s(<`@Rg0j>h0fDLgkki}0TX{=X&K4N~oP z5NuhB?QRdYUWDhV)^o(`i{bSbh}ZY1*Iy^EU$3v<1l+E5aS6D2!h`vA!c{i7%IxjV zzk$lt9iB1A6E3DG7avAEXV*PBs75b%@P15qxK4SvSM>{54B@&&)(&Z^-wNcI)D$}& zehjuA$g!SiZ+ON|n(aQPl!n~>p5VGxam^!qoS=NXgK=Z)s6BrWu4GHir9`J{xb`)P zCTTitYvskS1vs?u{=Go6Y%#T;|37*}G=KwT!&3{F>uG1c4 zCwltcLO7hH91bM<^jCdSJbhOqxOXY;A4v}OjSKGye@eY9{K;ndl$h=z`PmD(*&8j- zgR2+G&rE3a8NBMs`%~am`D}*Wgs+LpR}&KRPL28Hh*tJkDKpS&jG03C?x%dm{~E4G zEf0x;(zW|zPFs87BGE<4xDKKA&zGH|7%jWN^PuOz(o zRbCGfT_>on^N44%;F;khwktHY+5~@Z#s5ph6PDLP<+T^#CJEe(Cu8r>u?vgcYpDYG;>GyK&_uquC@ygdlgzrAe_ZSjWGGa;_Q+`cub40Y1c9g7t`ylUo z5UzVE*NaJ9+cmCyGIpAdeT3xC{Xq6Ws(aoahRU&(_$M3w*-N+@5AoMB`0E6sMNieD1sOX<$6iHnrvi7%ZSFa5we=st zy-jgHMmX=KoG&2Qdnoqq5$rZ+lYw34r;msihQkXx3ARfDY>DPx;*}hDWdxYzr%Jn9~b$8`@H;FkN zG2cz%x=7o|@sRiLgjvi%BTTA#}1-=gvTo)>?eI%v~#PkE`KoKccU`lBWfku-EkNM#79O8+5cw#_=2kYf_0S|S}N`k4EVoF=?)^;E? z`i{gqMB}}YXxKqDJVVEplVz-I(x^3qHyS9|hoJGGcaVTY_=UC1d95nDMul zKW4VMFj!+6LA-uCygnzwwcWR^dhTuFoiXsv6NIbw%GGv)yOQF*i+G>_9;g_J$$DTA zVv_p``VyWig6C^7ZY-CwuWUJHk=aT#D1-*dFS&hl2qU&vPf0(a;_?$d{|laagYeK! zd8nhY*!?WWr>Q=-5}qn5PrC@_%D{YfL_f<@n?S!YrUl_~pz=74@K^~vJ{aNA;+JcF zrxQ=fyY;>!e6&?QxBr&e#iULShNmZxc=~BPpL@J^8&3ad~=tuZ&rF_Rd z5_&{-wEM}=Rl)Zgq&BUGx7reK6~SBIMtHWhv_-)481twHZ>?SB=NyYk_0r@H= z9x8^1Iw_}iAA}Wb)xl{k!dbI`v!-UmF7BbH2p>I^j~&QiS4|y{9G-x-f#}&n_58)- z(MiDN^5|OSx(Iw#2*V8iwXv_2|BZ7Wvq+BDAUt0eux!j5B}8Fw4u zqPcQ0e;3!G6Vb3~pkaISJIS|U$hRC1rcV*8i$girycBp`{I5~|zaTtyQ=W=E<6cO- zTm@ck4}Ijl!}dNCtLvrEXFJ+%v}*#bK1rTWw5SO!>UhRq>*0Dd;krq{bvsiJ{R%I3 zvp8`z8=t{9#_S_HH`9ndA~oVE)QCnN%*P1dU6t=X;7#s1x9_pFyzKy2SEB6x+IO5= zyQkc1&_!b$@5%Xv(9PC&!DX+>Hx6`@`xK0Mj%d?Vwdq5!S5fS{cDcD*t=v68d|eg3 zKA(8C1e{GL+HHkq7olAeX!mJyO~OxS<)`xs_p#(~)PdW8o$>xY;iZZ4GM?~K9PrY{ z>>|FXi`eR+)kiyvr`gv-jxW&I5Iap7e6GCx{2vqiD;57TlG7uQ(^E)n zatD(5v8bP$n?|bF77}}*#{MADr9q&}VDkgPzCy7tAo$uTzIO>Pjls(u;MP^IWPNua zl0(+3XMpWZ0q0mJkk|?|HY_BZzFDr=mn(MLw|tjuK2@=|Alx=oZofusuDP-aVrz=l z46XWHx3{VzCmu(PQD0+ts2&~EW6VaveOtwUr}AUtv&T}cz>lnDvI#$B z%Fj5G7bhSu;t#ox3z{S57HItmcMX)gHxRpP4Y(Asm!X}m9IQ3nT2&!9mnqJJkvJ_+ zE!77X5uVy8Pj`^~8wn+TCK}XL4Jr~IT7rXCXblMVrHcJi@Zeh0tw8*%&`t|@FlI90 zv%d2AGU1?waIr_(tp;+VCR#1D+GusqO3><})kCX~)&Q*`S|hZ^Xidp#Qa(Rqswh&q^Mmr_Y44)}i z)(Wi++BlMf9l*(*#OG7t^Bx{PP9a<_RxUpy@wU`>+Yo;YRDV=eJ`rLt>)QOx2cI%G zol3@Eq~p&eF?U4FKND;%6x#-m7W;?~O4JASBe?Bclczoy>*2JwN9W0r{e%zMcbec_le)9!S9!Qbl*?%tR?cRHCkJ=vk2Fn!Sw`B%qM%e>I*(%bKmMN zIWRrar+sa$*^_QA;lZWTa2!~z3 z;prZp7Gb<3^litn-C2;lhR0BHeYfyU%n$gsI5NO=+WtYa%|ELUVoDCHDCG4$#k##rX$ZL zAVF-P7-FB<30#^BE+jERE@X64P9bX(z@`2Y&lZCmT~$ z@Le6PCRzzvJ+uaBYfbBf-2TMt%J}CPGqz^gK4ne+8sVWkc({PXlBu!GBpf$Zjt9Tu z_SK7s@KM5Jb>;B~!c(dB^E|ho+anjc6R*#J*Xt9mYARP(l9)3z=3@lc9L04X^oy-K zHeZUNl$=NWg7Dn~d>;WPE}dkKe%1ubsqW>DAVI$S>eb2Z#=r=Z2 zo4>P_i@OP~G{to_sXOCPclr>WYN$?$kB0gqgmQJOCwTmlc&nOv>kVk+I)=}KJ_Tr% z(bk$1%^`w6Rq=Nv9_#=QZYR7pR9+VnkIsZg3p6&HrxK%Vy%5_m5?fV`?PY>FMKQPV zcwq+Nyt;D!BX~;&4(nJCL=%5^BA%F~p2+ya?U^cyzX6H8H)6k&aN0mQ{gA|- ztg&B5>d`BxM=MF})in011b4CG?o4p^0q&!~<;rWx&4ubA(KlA_j_}aaB;NWO?-lTn z8)LgTleszlPPcdDGcAO(%N3W+Z|jX2 zit8AuOGi+bo*{e{D__@;zNc&74-@Zng)h3Hbw?WnUc_H^v(KRJVEUVhX0ln17gl=W zAAbKhXuZ+;p!G%Tht?l$09xVz z_qw67^10W;$r=)`R7dgX+aAt}&2U7GPckBL)zr9d#rVRz^|8Izr2w@_u3t34YYns9 z$1L;Urw<6PQRilLS%-y?2&SOag=ikSfvwh(bVubXZarh=e3=HlZlkuwxf{@4YMf z?9cLSJlnHi@7-rF&-(wKnR9n$XYaY$B>4OM7q3Zn=AQFC-}629-YGk4&_m}6eIBMl zXTJ$~Sgz_?$io51L!F?JzRcB2Ld=~w=IaG6`-98$EA;aZ&1-Lyl zpL39pKLl*4j4jW=%YOtu2Y}BJ0w+tDlN*JYdvVOI|BTh3(pU%9*ug@syKt_Lh0b)G z91NYULz`@f>k46yUu@v1TF~A8(A;daPW|-bbsK1Qk-*a;=IJA$=9Z)0R-pYU z@HhxOZWpxCnYA%n;F)IT-2z`dSeNAnKGq5`E##Q?@o7hmtL>m28o%xo#>PtMweu1u z|J29(8jN_a6yoi~@qQ`9)SYA6Xox8!a5WEH9VWzk5XW02#M_qRJs0}Xt=;B8J4I;o z&<;eKk5-Jf0PP_9DcEhpc83UD?FFuu3VmC1-xCa6Sa<4=%epBZ1+ESRS0@WxEnu!z z3Ai#D*KDDdI-r*NZPwS>O4P~s!dUhO#29 zI`cG0;Gzq2aRGCoVp8>A3@#Q4@#G?&_l5j*;QZZV;PHNei}}pODMCzX9Mj%HOr1HV z!=Y#0{M-q8?uOR7oqo+y1?`+C1p~h}C?r&r+Uhr|P);b5;T=%lR66V>3(A{FRe+ls(gm@>vtREZRME$=5zv|eY zFsWlqe6s}3;kLJWL1?!LTqkoqohWcJ6r8LS;@-e+FG;eS00OUnehuu9l!BU+LsQ zaj7t+F{TYdj_Wzcr-M&jov#B|>(SB$`>AYyf}n%8tb<<#P8NfccLl!bt}0q@9VcL~ zW9*%L*p!Z10vpxGbYRo1$y>m7FQIP>?pr2kkj|~QdR#yDEkR608a^mDt(lJ}kZa~8)V)W~6i{|xs3oiOGFP$`cKbsu5Q#&g_++soT>#9axU>iAp^Mze%mwcuPG zlZYXp{ctPoc^$Mva@&l==&nZRce^VvI~AB%fI$NkU_5aM2exK9^wr7^DE z0;jdi=@@XMv;nTe1k>hHCw>iw) zGJ%(s;N>M@OnVmPgzybkSIf%g>VeVV{~8^(P}0=!=(@UuVj(+hba zZq-Z0Nb8QxLQWPl1ng3Y1?;Ywhj31ak0MHv8Ie z$`Ya8HXu(M(Fz4l+A=543B1o_-v0#eblz3H+Sw~_y1qsCF=pV{rW5X4Bs^=drl+Ig zdiecsiwHQOF@#=}XXhW;a^}&8gj|#%54WIwgZiO-`|mqC7(UjaRid@r-_eBPn|>yv z&qL^y1ayS(Z~;dqlEbmErFXE%uThx{U-3f8SNvX|8(xZLdZ=U&dtjLN9Ew> zX0)D&-&@~`2a5YNj$753;(q|g{a*oFA!C~$Xp_E$@As4MV7uN`UW-*^%3%Lp* zPdB0MZOGMm!dSZnTxJTmCo}G21>E#}N}A6;5xAZPuJ03K>d!HC6MRo%-=%^^j)F#J zAzoGgqytsQq|FZaJN*g$8UvqVv2G;J1WxEq!Z`*mcYqHyPpDCc#)KNM(TX{F2Rfp< zQMG|z?bje^XuiSrzR;I_&qK_JXxZZ)eGBR#X!zE4tS_sr2wELlJ=zAejcA+DHlsZ) z@E%~^2MN6I%e*f$V7!|3pkh;XPglf94}ApQ*MRdI&{i4pwgLTL5wQ1T?4<^5BZRmn za$I!Rtu8Nx(CXuY9u9{d#tC-!VY?RzW6CEOQx0w*-V>p5(y6RY zOUT7^G&``~Lcx&q2*^GxXhn z)%r9c4;9G4b!aCT;(C#JrW`pjIa$hJp05zb&|{&klyz}1<#QZ=CT)0esW zOvpnz=V6Ax$4c;VCH&G_T-jFVoQC6jYH2>BTAqpDHwf{K;rQMV#-UGP;ad1G&6hh+ zS32GgMO|${TPtw44!m83b_49UA`$XSojZ5%2XW*|XKQG7-G*o8R9TM+_bx z1Z}1<-xGv-8-jXkeVATDN88?^BZ0@!%;Rl{#j7zjHd8FW3gg;(&hrU^?Y-Ida3QW# zj%$_>S03VekaMW;D6Z*hDJdv`xCyt?k=lL?;yzQrHHvX%+^s(^S;=u7DdfKrdA$Yvi zThOn=OQ4AX;8r&eoeyp=MynL^c0BU-j^H%>^e3$?J{N4~ zu;G-YgDy`eAP*;@b*a?n5#MZtbzC)`tEtyODKwCDwfe8ek1T*2ENA&xjGto+J@HlUrsL7yg@ZVFZxvEg=p^y8X64^9VgVq*Qkq~f`+z( z>r>FOg_s6%OwS2?bOIksk*ib(ru~2K`60TeYJ-r6%MsNz2HlSoFb!Z#rSR*m8MRiU zwd0LGyK374oN>NY$bB;Bz5;f==j+vH%;;0=>GmB!9dV~xmG!Q`NoR19Bjm9bIlKUE ziV#~C$JQxHU$Y@-C=7i1^}ma+D-h-aBYo!bWg+(`Bk!l8l?s|X26{XeZ8QA!h8@M> zP<#rF&ci*3O3VZ&bp0R=E5CNQe$Weh_Jik@xMPQ|p_Sqeoz=LWP=UMT*5S@Cx~@=z zvupS!2%J}|$N994IG45=&pX^=Uu~oF4oBhmi;i5r75MD}erF5(^=JMD3jD1Ge^2?e zq2>Y_YbObLiy(^gDR;u0c_kvc7VS82)f0Bqi@2iK-^J1WLd}1J%)B7zJc)Jwr7-@U zh8(OA_zf_>+Yx6U6(oKZ;2*u*IO*<|&bXdLis*x9&g>~w;QaG)eQk85u{le>wjP7= z@pNF;U56sf^mJ+qPr|uX7^|*EZWjyMsDm!fLpxrmqvN3Y=3P?!&%^37m8XCtss3y2HQ!nd9H0F1|zi8SNLeKhXX}OG(0=cW4=CtZ>MDR&-w{zzYe&N>+@OTc|d1&XO4F+dAJMHjE zql3`rC?T&0Bd-euPI`fp+lAPAa%`6fd~XETXQO?{W0Z%hqxfs@|gWC3zQT&wkivUvgW za3R|50w)cn0&H3()<* zyN;VX;JZlB({MZkVj=qO7W{W(|62wA`hdU31%5Vzo3qd=z^@M1Md0=pA!n7y*<#j- z%7@B1;q3@M=o!uGm4zoV)61FP>2494-PPRQ-@a=^x8`$Je6-$kR(qSV&bwU5(?sN{ z#dK zdcTmXeUYm(z?p7-y9AtFigp>=2TV8@=5)TMs@Qe}|$*7otMLeL-F58_JM z8&Ad}G*mGTB6^xpsdcF#*3Sk0CWF6aJ{>7tP(Abza<&!uIt?u;S-;k!C*?mV5henY^m(=k;t**;LHfm2WeHyXH_C}5jqW9wzlJjV%Z zp8KGThtTdZ*gu4E1ET#>YeRYt#~_@8mr$7f^`uJ9Udw}muv>SxE<40`WADDG>eligE7Bo_Wc;6Bz<#NLuM&Z4`XubhXb%bbeFT`lHTb+c*mL!EHOlnTGx< zJ~i*O!coydXp6Az0)yXw!>_kLjomcvw7|QxZs?42b}NP4&p_@|ck8kJgfa9g_|?s4 zD>+BKfnB#fkB{k27jkhl@^BK`20mZlIXc5c5;eC2d!0 zQ2c7YPKPefK)Y3lZ8XQ0Bg8h0WBW~*Zy$$_{)IM8sHy9a^Xt*-g`CVpPCoVJRB3`f zCE#S#vaSKQI!$c@ucg8mIGA<(kP!O{j(xNc`%sSk2OsyOUD8}j8=qw@7W94t;=W73 zeJpT44P4&i2UQbPUsD83Lm1Nqf|epQ)(Bkh53c`0Ec&@66D#cjSpN*eGj-kRDf^Dpd%>yhSUkxL_7<0k~P_yf+MPFIHsC`XD;rK zb@OZ-lR0bW1MyTJ^0yG{`la}E_d5F;)z@jgI_dNM6twn=fwz_dW;KVj!*T52bsgeR zL5E4K!*7MT<4n}&JR#pXobL?8rK|t@G3uq@uKTwQoP>qiyb=1m3GI17qsKv`9~tak zDd_9~=xl`$Pd3MMGPu%dpN@aK`(jn~_JAF$Wqk!qUM|%3O6k(X@npsQ87tBxwK8&=zNO_x5I@T@WkT8Q1FbxRf!E z6LfGN>);kco{u*8y-48v7I1#IkY{>U0crC@LDyNVYwIaJ7bk${Ld4^}kH9%frt=-n z*;D5l{q;$o3HjKFeEbJBr<>L2s>*^7`kY^p!2LbU zeS0C!6A|Z~0>8I{-@yXD#f-07sFhtn^{gS^g@OimK!Zz#SnlOmUgn%5y|&KPctTHO zpq!5oFz?Nn0|FP9fQz&g{rQh&+e*jxmSOcd;n zWV^eB`QkR@?{>6mgWr!0IhrQ;9l?I@Wj_3Q$Y4IM62{nHF~)B2%M zYkvV(0pl7g!A~ChnI-UgHF!-~sXx{l zz`XPss2>OCLf`YyPDKnfZ>g8M2c7Vz+xH$>*7X=`bYtmr7;9cYD;Mw&WBdmT+lTV@ zUxggpi5z?=Xg!^|>xB4qwN2yE#X^4WvbFB44RR?*0=^-PudBhw6hT{uLR+Om-mXF3 zdU4)}cV`@RRt~K>Z>I}-J_mZp{p$XzltyKsEy$*yPju33;use_*Eb*Jlg92ea=X0?&7Y=V!pPZq0wE zt$EahV0#eTK1tyEHgNq9L6he~lPiRAW8Odknj*B!_s zjm;Stx9A-2aPT7OdxXGQ3UgK>;P1=$9~3b5XN+F~qxYCconyS6F>b`Uk*&g5vjCb{ zEBNoj{?8F|x)nKn7g|h5eW`0wRBQA)4_Z7Q?EP6M!ZFapJY)v%q zyI9EYJ;-mZ5L<7K?KuJ0BF6O>aM3kirFTC2ZQaV;2IKA$rlZ>k-xs{anqk0wzo6;6 zq3Ld&^~Yte!uoCjb3evBSI}EB>+NuXlU~fpd4g6Bf>x>puI~lc?+Lj2GOk@5uPqP{ zry=})m!L8FmdB1ovF8=&o)CIDYa_agho1RTib}Msr5rnLcg7|sb4eWgb|Ll*j(z{v z^>gR%m=Qh~;_Jil^#IP+?3eu0T^zIyy@j>n-d{v_l)E}ft=8AjMcC(Jv`f$~MSBJO z(VU`QbZ&!Qq(S2FdjVf>#`m7Dzp7cM{}$_faN`}r)VcWyIQMy%poxXh#Ib@V{sB#V z?8~{b8Nz*3VMA^FA;i*)V;Ksrby!Igm;2&SwM%Q!nW!t>8hSVC>MgXF1RWj$9d0z> zy@qu~`S9v4optqJANT&;jY2%$FDm|7F;EIocIySE4Nw z#>6*}x0I)y@zM?m|5G|EL1o-;(8H;Qoc0vr?#^-VZ_wbkf{u=aj?Omtd|c3xW$S3R z)!G-QH&26r*IN^68(p8d(BN~YP`?jA7u|gR6t6+>y3`lH@<*f6FoC;;%-sf|4&Om8 z-$VOK(9~jR>Kcwk`BOP>0iBlulWyI8qpdf~3i#qtHc02^2xI?W82bkq`n|*YQnnPH zWaO-E3ujFAZ#xP)SZCmGq9K>dg?hOPHF7oDHE7qOS7@z7jPnp!HvL+ePY%NGQ$Gr{$2A10+CvKtcYc4NCg3i*8q`7Jis zJzL=EdgiHhP_O3}$ZfWeo2AIj`$C+p5$6&ghiYBote5bFY$4XJ9P5cfJzR$xxE}2W zv>VZazPMG6X)Q8C$niGhxZKchvw*D&W4jJ~dhchZd!uMgcpdn3jvwhNMpxX)*%xcr zgROUjG04Jabp{LEw*>b`3phG6jw&GrQt8veSo{&{<}_b?3pmD;40yW#LtkfY!RrHp-fx1&Z$`TX?N+qY4fd}UuoW}5Lj{hH1;?-Z zI97F(g1+a%r+0k!*YYm{&tHJ&g#yoM;Q10mEQNwTA4LxC7UG=GaYh84Er-rNMV#r# zrP3{(lc(CfmTQ;p%%IQJT<624_@LSvE#$Es@_3fO@p0hzQ33aXjQbA3Cyiw}Z|Lha z31dj-F8cEdUxEKa1pZrr|KEK%SDa8?{To7_&ovq4hB!U`SlvG zL~By_{wZgMy-?t$9k}_QfPXgQpDNVOf1$3hkmnA_bGMpg8>4zwo6_Cw(A^zqccR^e zb~oBiv`>9ps2q_N9}@Du5_$jH(67by`s1PlIJRGezI0~kHi5JD;H(Yo>W&98VVCZ! zqt8&c6MXN_zV}5AsV>z^<(|ft_k`S^h}{3_!>sy|W-b-9_5`$cvXHBe$kk?H>`cbk z*#mLtaMC)yp^X906GA>aAfJ<=Rf}tS!jgYTS$X8!qKX0v!H00|M zK_CBuK1K_1bl^C)3i z&)dMc?wsq@m^o5#OqPqhbQ!E)OO=896+*0Zr!kEQvwXO`@eCKZKN;NrQy7C{bbJ&g3{dtUFdW zdHG$)OIPIOGC{xpfPSY7+AN1QPZT(q&K%Sm;uy&ssMr(-Y0SY^L*E^O-$M5Lm?7U4 zLcUK$zK=2ZoGRc=wecod_X-@|2M$j**lqcyK4+<@!=Cr)$IfoZ+121cS|^MabntKJ zV21(Ad4_El8MZBCZv1*~!MVKMfb|eTUm@u0GK0?#edDUS=5v)ju4dp|SCw^-!S7WD z+YcD}U1#W5Ch(BLJe(?M?=)y{tdQ&O$aQ8{{d(y;)cj)xtWO!X-HkZB$64w)HfTB5 zd6xdHPzQwf$@8r{*hH zpB6rOSpr_hW=uk~o%KKD>&D5T0y$myqkzk?TtZ&98>$KNj##WxV?f<3$?A zixsO5Y>4$Q0n=p0^o0sxI19*e5uZFS!T9Y0?W>@+qjj!Ad)8i2Ly zZb27kKo=P|=(ReDvHfg_>kk1p;n|8O1x^9ix^?K4_IT+$1Mvz$2QNSeT?B0VGPZm{ zdk;c;$OJ~N=e+{>Y~Dot z93t4>hi!L*ZSUBrYGS25b{>Hw>hpgla=Ze0(2Yk|*m=Nb3w^j1S2QXgD%9GKsI{|& zaUmV!!lOc7UqoKt02jJ-1o1Fd;9&yuaFdXq-pJ2D#E}Ub^irScq2H4c$9~9d30eWh z$)#u&XdBQL2^x9`8v4k9vrxb}UTKp#Rrw|y^lAw#E%wr{zt#fZVTSSPI|H710-kY< zXMmuOv!IV73_d>;^7s<+_-`Q>eUOVwp&Qbi(vlrK{`V7f^D~-NB5PoU5X)GOWs8ur zhmo_J1ik(OpKT02D+HfoY@h4XE--MkM96h2a^2PEQ}L0Bs!u*juY**mxBwc_@mB$j z9E?^c;BCVk%@p#z1Nq)9)NLl}_G{!+jWf;|!&UOJ` zE5`R9))pC6HtF~OL0hfv*Xx;lK5Ed;4*1lKg~Z1M10U;z{GN^c9w+EA4SIYQSajF^ zE@K|)p3^Es*BSBX=8P29K~NaO)uCJjXzet_vt7vJImqMw zY*&pLgw1&!jUUHYUm9Y4$l!CWke_}kKR&z4KV5GeFYw>S=0C~$m%;DPKD(-h=$Pp^ zVZ5t^o@&r`3Yt!brn`01AA|e>E&XZm`GNs!@`3ugB&?eRtj^9|Rpf z3LU;~z;u(Km2;t$)&{&CuuXUTKu-zpU_TLjjdi>bQ!9??0|Tzku4nDTb$m^C zxxhyz^D$h=Us4k8mo)fYB-CUZ)Z|ZweisO_W^kbuk4UTtOE zsIL#2w{8>oO=o^DW!q$rUg|uM^K|(mt&RrUCkPy8*c?x6ITKv9f=xBHsOM~6#Pb_H z3*UM6IjtA)TzrGC8-Y_dHxoZ!3pzL-I(R~eKaJzR-59@R4K`q!D&+fd1=aUoXq)q z5t#h_Y2TZ;W~U<_|8^ROTk`t#O`-qQcK<-q90MPZ3)qqv+YbWQEt%^hSSPA3)jemU zxh|HO%A-0x?E#+v3Gu0=S(<7}bgq)nu?AIA$dsC>z z4yeUeM!$z!0p?WYgML!I^kq&DH~8%U+tS={p`hV^LBoa6k4^&{p`E*Zxlqr07-jR& z9rwu9U`2a`b&>&BZv(ED59sxmiX4p+xah-NlnENT2pW1=$lrOKzq1T@2O98RYUr15 z==Y+)<47A%C;L;C5qxv>8N$5Q26{d~;G;M5@d$FPtA{6%EZGJY9u6O*UZa^0r==9Z^T`0~4KlQ7`oz)D+C`9dOmt`4*Xg z)gS2YGQ>9B;J;27R}Vv7Y(+aoi0f*^RU+i77w2j={8FyeD|Y;`tcMMl59Gf7G2%&{ zbAJFg-f=*Uk94fO5Avj&k5lk;O?tlOlLo&R3-Mlqcz-ka{7e{oo`xo$Gx+<9bFAW| zbsXt#n5{c+mUFEc92fEFjG0caWR7c-kdL06k5>#h9uaD?Eow4#e(d^29cP|vW5hQY z8}xOqFzy}!ZQU$zeJ!|NZ?L&g;30{5c+U`LSkTqKSXbSISPMAT)0ks_4pNxoFX3CS zJ?C8OJfYq@q2Bw!cN@+v*>8t`q=kIjx4QS(dG4K4{dDHlxt_O{$0q7WFQq5a`=bKS z*Ma9B1iTr%ZadPDhxG=Z9c%T+F3+GI_ClQAu~yyBagH4)eP3F@n$lh0zXgt=?-ew4 z6f_k!U^>AN%bx-d>CD3wLf(@(?;8Y7Vr6WPIj0+ZeLAEt4Br@&njbN7Of&uz%(Nt{om zXItF(-$cy0g@TUG_UPy{fx8>P-8BYoN(BA2g#LO8d?Yg;HyiAZ7wY0!)Wrb7ZW7yl zO5l;$p!1&#g?#4u@_DZT-|qrnH-fKW0zUc{iH`99rLdMb7I{1o?F?b;>x{AQp9V}N zLY{Yc@_ZfFpVA5aq_MLTo~yeUzXkrSA5S`4tc| z5;$rHj>-j&o&!e@3-NT|c-{madF)8GvIMSf23Ln8UhiD1)+J}!@#b3d4e@+n;9-}5 zxxJ0Kr`07#zh*xk8vop2_i8~CY0$(0f<8M!pQ{XUl=-%)b#PmpL3mw=qaAafQKr{n zd*t*8A*atHr{jd2+=86^WQhM6q5iv}{wob}TqxxE3_H&m)?Wsnp9mbZWe%?P*;eDm z>9%duj=;kU;NehU)~#b^;`$5mPfrB@LGa&({SOdw&;dD^C-8hLcy7B*J`ZvmV$zLE zbPerUL4)bgU^j!!;}NT_)~0i;I|Uw3V;*M+HM1Qxlk}jYL%_3NO2dos8K4b9U35ZS zTr1?}MdYR>YYM@jrB?=Y+6pZbZIUl8g_Eum-3m^0H9&Lo`-b|sLeN`h z={N4k#*0YCx9oZUs zEH}in1GS*z_%zhQS!i1YeRQUIK;R;sxo8D0bYtCi@IYh!jeYvIaitK%IDz*-)jWisf>HP zkmEMU@e=}<&x6b3*rytY9Mm+1ZL=;C^4kUZ4GVZ$GM)#8ar6x6W()TvUrt>*-jlfR z0PviNZQlEGY2Q5Df0Bnvbh&RACoxonGEo+@yMZ?wTbe6NFGdl}mG^u(Lve7vZ6 zd$G++#F{8R-YXp-#*^%w?;_r4U+>v1aM>DM_7-yV zALQr&@Z_yuHP6!%ZN3q-(;eD53|PJWRIF6@>sZeeih7@Ze*>rwH2CX~tDkGnhZZkJ zI~qQ{*VVkwf6YWJgRG$#A2;E?f=|*G8T_0GJKi<0I*)w(NFfzP(!bCtpN zD}v@* z>!gJ?27DG?;Pe%s`$34k1;>7*VEZ83HjYOOI=@I5x8H)!?=ke-F8Ewv`^>NkgnZzx zRjb8A`ukc^IG&e2nUf<09rmHINyx>k$i*@t z|Cb{Fm%^uRJn00Tc0d> zj%ObOuJwj^o)hfOWxJ;cxw#U#sq@)Y^Y6a+w!xsF->%5b7GFO#&l10L1#Ks>wr>(R zejOaYDa2C5vFt0OpCJ$TaAT{Fep=vu9sXZo&{&oM@8d$w-ayWN5ilLVm_8Kh zrXT9&VneJsz@w|FW9_IiF!Nj1b|F9Ak)IiY9=bvgbplUI@cjPOu$z2~e$L;YV|pC< z^J7Cd>m{s)>3M@&@$Yqkvp2!nO^Dk&POIaG-u5_+Z-VsTbJk0$!e||5S?h&57=Sux zswh~l|-m5>nefM9^mvoU%tHK#i%-c{k@AC>&=*8-X7-_rrwO{ zERI)UabhMWop>Mf`BnSb zV!*V>fT_##dY%HPhsy*WTG>3bus%0n&J*%p$Q-W}>ggCyJv}1iz9({jj-a`L(A@V1 zTyF?k@4{NYLx?$pbKky|{`lZ+#( z#6AZwW-{hz+40btF&{4U-(Kdv4*Fv2mGG^rB|2A8=Z!lxIn;)qsh zm-uXYb#a%FvyYIoFl z_|nbhvD~T`a@!xdz0MHxw?4Z{>s>iN=Lm79aei+%*j~pvr#f-$I&3Ff%kU4+`V#p5 z7<~T@T&l*XmpZT4#m3bW*BmVCQ(^uZggP0FcE15z%B}8oMlZI`9QP&xdyT*hRq9i8(&Wfaz3$e?q(rSNnDwF!%BKRkhO5_FHbv0cPDAfUfgafvfSTMctV6 zG3xLwgWoK{ZwK~!i;(vL$orE5&n=keUxeI$irjw$O#Wj8gke2opA8FH3lT3}J6EqE z))4zwidTI~sWYyB_Ow5tm}{x$C6-!cs3Q8V$_m_zwa&i!Tw`ByhpS^(gOM#0AnTwU+ zg6cuN`r>{wddXa@!kJ0M1ATg{+WvI06FEh_&B_Pq0+qY${7PL-x+|fCUrv*(8L|hjMW6@BIMQtqs)1KGS03S+D?bwWOlCfJ3ViO*d?pQ*kBRpKJ~i)QS9@pa-GIw{4d}|H^%P^%u|J$$wo}MLM}f? zF8^e%{o2f7u9pg!GFg8;3|v1d=xZ4CRqC^=bkfSUTW@U@#^_H_p92g&-xaixY%Rw> z+`|IDUJl7Gy*gpM`%}oxV5${Cx46T>9%ZT4I`JWH0ymPk-F#9d!Jtz ztAV8kjKhRnWFr?{4EX;o&P&eq#Y;W$5q@_Z?rh(uMKuu=babSxqiX8`VT||`W5fm_ z*Iyym*ZOj%cx%Zz*&%2@7upXPV&2_A%m)hjLMHLgvTpa`Qd(-kT6!P$y zP36m>8rSIg(}h9~bFl3mpHIa_3UiTXhoKoXnUiLK^uoQ0c|4MB(y1Lzx({FImGdg@9BeoojzziyxkDjN`cEE z;PNy>zodok7)8;j8YVpbz{na@@+Kh{?U0K{ggP67I=e>D&ezaRkwKGbz(n~~uUL*c zSy{dH#}<7t&cETypQ;6mYoRr4d+)PTpU>ZFkIwFA9WFF*_JQEzPhR6KF~oL-!ET+9 z!=cFGg94Y|fXlCZcvPMJW#cKg(l_Y&`V3=ixll_M*V0V}ygLM4w1+MZLY?U9Hy<_d zqfg^%oTGKrJqCZ<1%8HspFe#ZsJ#EiIr&`B=}_pjUf^IqJ{EaN;Qm{1|A+zaC}>Sr z%QV)f-R5eXu&SK>!8v=>CQ)y7lHSj5`8XmxC9bCh45c z7Y43ZfNOtTgg(SaLCLN4^Y!=0@d$y>pBdK;225jxzCYQ0Bi1cKo~Lu3e=@}Mfsn^e z$m4TD4)RIsK1`~{ezY-J*1ZCzLdJBpFgA|B*qAiT(T^Gv9d*!i6}N)_tyXV==O4iH zY#%PA+aH+cRNNstTP*nfj{P2Q7!&>!^4%Hvex5bx^+$e_aHMt; zZ0gQ;ZLziQJOgBv50}!!x2%aVLf(Ev-qxe9vhVbx`2f%5Mc;3@{~rQhBfwY0=Ue6d zE9PW0@~)eU(~$Q~zP<|gm+W`8fcq!l?zcu?^IgH`_kw=1trhq;(0Ux>m`)!7jAQ-L z4i|8J!MLheBmR7ighuWV@>S-^*KvaV&)I&r6X%&p;5H^yh$ zIm5G%1RbSAN5cfZMuD%3eSVcbKe7FmTipb|d$Hdug#I6M|9T93JbZ&KrZe^Up0P0E>M{> zhLXaD3b^piO8944Ckb5s4_w~w!=&=~0muBRu%`MNH8D!?JAnPp5%jY+^s`#XQxD|n zQ6DD7)BDWRM8R(s`+ZvI{|@)ROyJ{J@G(QM-QTv|(|SPA-rmsOi$1@K%lDYeZhiFQ zV;0870cfWQ`EP~%mkC^s2AAVL(2r}QF?OWl!G^l}FJ(=>=EJPGew(?PEASCuu8$P* z*b{kNDD>^eeLoO7`wgL1FA(_b1wN|;-@V!QGXh_~gRkFwF{?bk$y|RX=z27C zT_^bM#ePo{xE>3x3k3Zg%KF^(fmk?`T#QM9y-=E-biICS4&g*4DJl!~+F9iPEfd8H^>0=oKEsg{a z-gPzUffVs7cz6wsuEE?W`0mQSpAhme9(kDLvrmd5`}e`_{b)4b-XqxW!uGqg(XXNZ z0&kxQeD?$2vwgl*Z2y7Rmu=sr)}w;&&g}bLA+`yKt$m(;o@fisw;`X3SA=M1k!oqP z{hM=bXrT|E;^uB(+iBy&^$uuFcMR|ywDvvPvjYB3jQ=@ddq>_rP0+?zXyYEC_Qs?3 za)g{%Ndv8vwfcMokdqR`tQ%uqxBN#aewOs_uP^*dJ+5djjr3^9rw5h zIctZUO&4NHMobZ(U(yog^99>)xpki~UJSx`(O2N3KM)=2vrCxC?!P&n?*%^EGaok! z^Fk0_JOYYA%ALJ z?pP!b^rYEs*69MKXBg91f#)pnocXA8+(x#%cvBc}g}_ByoXc4#Xr?_hbD@A~7h~!! z_)S(k3H_hu{;vw-$R^J?vI9BRjS=IK;|XZ<1zrY#m)iyZ&$9n)0e=$XKMuT+ZN4cLD29 z#Y6kiYZCO=rmub;9gG_PmoFAIK0IZ|Qf^fXIT(l>Jcqt&u29;fIr0hg{TFlbmr&4p1R4&CFRze>tCR)uYEq1rXS&494KgSGPL(7;!)$5*EZF{v4XZH zLtDT4d@B7s%yHHTab_USTs$;P>4$u(duTR##)x}_9CktuzYyk#eUba*JM{DQL(Ii> z0>^{F@oobbtp&Reu-&7Dcv~UfcMW!z2{pPGYP36iDxN5(YCU)>&L=)-`#r$gEaY}7 za{H>lVP|l7mVmc4@Mig9Rk^*Fea=VzbYtjBuI--<@jfl^KM3>I-GbhxKyO|CqaVvA zA?HH{y!SBPtAtqFAl8in|2g1)j9~Xp+itn_qrh($@SE9IuB%Cc-8BmN}R(tbYMYAm?jwvA^E3Gog=yl)HqPX+&5d^uN|*kI=zSJ#C6Oh$f+1x&Xw zrl*8>+acb;1|EN7EzuZ4FEuU_4?TwK=i9Exja8w~4fP8OSZ`&lX@j z7V9>F`(fa|t-)@kfaw;-G}XXSSA*RRg58_h?rw}Ny8EK0VQiU>HWO_Y+5u>D(B`5Y zh*pet5L!sk#1v>E{X~6!ra@~vc&=0Vq}GN6$J=7a`_*~$&0NlF3aq;P@;9j|Urk zJ}LOThJD^GXlWX>bRsyU=WnX#N)ng!>H!XWqV+=Sjn)UPFIqpe09t>v4F*g%7-AU! z4s`sE0tY2%M;YwCC&YR+$J!nbDpKn;ibJhymwU#aurTh;KyIzg`uzM3J)UI1l_%tN zZ^UyAIM&6R1r7(Iy(Q$Q5cxUZ;PYv4Om>y_mB#ns#+8i!Mqt$O)0x+4uM7N5VE*O{IUNI>7YQ1g2@SOua9zQ;o)`2m0C5jO zn+6SgajSJ+ovqt2qF^zG!_Q9vh-E9GUqhNnYMUkEXe=a_p7*e_@7j|-gUvF~-v znZiat=`|LdO%`hF59EI@!S7}4_kRNJag6�oO1aS5Iq{VE(@AYAsdf)dIE)8QXjzmot&e$pY?9 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 B*bM*x diff --git a/vs2008.x86/ffpython.sln b/vs2008.x86/ffpython.sln index c593e89..154e5a3 100644 --- a/vs2008.x86/ffpython.sln +++ b/vs2008.x86/ffpython.sln @@ -1,20 +1,31 @@  -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ffpython", "ffpython.vcproj", "{A7E1C195-DF68-4713-A758-E27C6E02858C}" +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.271 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ffpython", "ffpython.vcxproj", "{A7E1C195-DF68-4713-A758-E27C6E02858C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 Release|Win32 = Release|Win32 + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {A7E1C195-DF68-4713-A758-E27C6E02858C}.Debug|Win32.ActiveCfg = Debug|Win32 {A7E1C195-DF68-4713-A758-E27C6E02858C}.Debug|Win32.Build.0 = Debug|Win32 + {A7E1C195-DF68-4713-A758-E27C6E02858C}.Debug|x64.ActiveCfg = Debug|x64 + {A7E1C195-DF68-4713-A758-E27C6E02858C}.Debug|x64.Build.0 = Debug|x64 {A7E1C195-DF68-4713-A758-E27C6E02858C}.Release|Win32.ActiveCfg = Release|Win32 {A7E1C195-DF68-4713-A758-E27C6E02858C}.Release|Win32.Build.0 = Release|Win32 + {A7E1C195-DF68-4713-A758-E27C6E02858C}.Release|x64.ActiveCfg = Release|x64 + {A7E1C195-DF68-4713-A758-E27C6E02858C}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9A7FEC13-457D-42E8-AA40-E26D9AB19D67} + EndGlobalSection EndGlobal diff --git a/vs2008.x86/ffpython.suo b/vs2008.x86/ffpython.suo deleted file mode 100644 index b561109b2c1c6c283e4585967a6d915043718278..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9728 zcmeI1U2I&{5y#IuP9P+Z650?#LT`*|6NpW0Cyoj>WF$4uE##tNV^@r>= zgvL||5E2RG0iO7JXkYtKK$WP3)K-9yS}9Pq4{fCar4K1W2vUjiRI>d3_s+4e*Y@># zZSf&xtnr!qzjN-Kk2!PZoc;4Vm;dV*FR%N+70@2H#GTJCcgtdU3RxV|cbqFj(DV6x zJ|BV3Azq+w(FlA&Tgz<@mr`oJFM=9Rgva?EDpK*+$~t|L27o# zlRh!+-5OVxijVj-g;@Z?S4bVM%Z<8zcbn^@%(+AS&(J21kIqux!iD4f5ic< zf5icUd;?qy z*TL2Bjqp~u2KL`mx!s<3P&U9j;a%`e@NW2Kcn>Vy3zX0Ie?F3Z_gq`+>7KU^pGsGK z!O+Z$&NXS5D4nzx7DB4u0;iefBdnVtcZ`*Dgjmw!hKXf4R?-l$7o%=xv@lScqZ1GnkJ;-<+#P%3tp|&Iu z_EY+v;$^Y@*LbzqW?9((N&62n^Y_q-Y?Aqs`mfmMKbpf2M#Fx}|DS}vN)Oatm!+RQ zjPqnW{PQ=ZJy9#a{_&A#b~9dD&x&!2L52R;#+L{1I^}_P*jgBJ56rp>x0JB{lzVkp zg`c5qUu!7FRnQ@4|$rt#c*@`x%lc7WC) zNo#wEHIr@ZK)aq=Tag<=yvaSpeteA8HPvo=xckMeD%+l_ z@jf1{vmU&@7gYI&f5XRTAl83Md#TO`#rmJl9)sp!?d);)F$2nV3fFii<1`ml*!ojU zDc1fq=z9NdqW3xhj)r+thPfzgMRE&t{?nO9Yr0tb@%ZECQE_mXwkYx{8b-6Nc$ZAr z56@#7(_-y^AKmq~W~%VW*?jXRw-?RD_4WhwNSUn0Jmbb~kEx>#)noztLVwfgcOP2E zus*r+baGqVwoLAQ^J#}7ZDY76^>L2K;4eLRZ?pn+I-b3UI)g4Y{WNfl(_)-{3QtVc z^sXD9jP7Tmo8IY`6c^L9U_Pg>xTQ*FS~pPr?7)h={rH8>Fglyngr^mq@O6g}&&VfF zM0dWU`B*TOrxw$-#&LJ?>@*E;>jmz+@OyP3tg=Z`_?Y zL_Vdc(?ydqu#ZR4zLIqEiyBV+4daetkEodL#N%HpJI%4s_8>Eyr8Om`Hvz`^4GY34ezsc-&ySVD~If`&nDTgO*S3AE#>~V zo|+Xt0ZJ2SmC81fk}5&1A|Tfx?+jDfX42Ujq@AGkXjbvA4oUB8`D=n3L+K$tT0@JA z&EahZk^|Sw_jHAIrUut&(AK$D{3wcQBkU-X=Su%R+D~+;cmU?OyEw${Q6w)?0Z!(I5tgp*zH}EaOm~1ju4wHD z({BLYk97|(OurxK4qh(U2n$m?_QCpIGb~JZ{;ja|egX^AIm72sw;Q&aQf*Y-LxyQT z=rruGVLCA;z>qbh6X96)dvqDtG7=Wre1ZK-YLTZu%``s z!7$Z*5m|MAYuHib)28>DVFB3dhMh4?b>Bu--H!~@=={#~K91@A&-9isylS(~apz2L zsbK-w3JpKB(lFV$6j?R`!*(NIWO@~b1z?*D+hUmNRw1iyqha!>O4Cal7J%JqSi51W zyB}F~Glt3YT1>CkumEhpuu;QQH;1gcCk>Nl_L<(3h6P|x8}_VWs{0(W>b_!_c81fY z_Z!0ku-6QG!!Xr-6IpfNHB5f+s_DINSO9j`uulzB-E+vQdkLYJL$g10KSQdG&=?xfG2{vT%U#!$GiGMZu zZ&t1Y`@6~iv{I*Wk@_Ue@5+iIH?ZvsuYjwNh1D9SNVVOt2E!E1b|H)Q8YW+EMphqM z4O29`#jsAp6j7UyMTZTeIqql3dUwJweP2s^QJj7-?*hKTHFK7$`tE(|zAppA8upckz>^hk{tU9#e zDSg-bn(j?*H5)%d-h(XD9fs)!szCsG$$T@8nR|TI*?*kZ_cTiKGL_mF<>8VmVSiFq JzAQ{L@g-w)c=7-M From b50dd42b2a544f48d1e5a319c1a9826154a50ae5 Mon Sep 17 00:00:00 2001 From: fanchy Date: Tue, 22 Oct 2019 20:20:44 +0800 Subject: [PATCH 03/13] fix linux compile error --- ffpython.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ffpython.h b/ffpython.h index 012a79c..f2d3807 100644 --- a/ffpython.h +++ b/ffpython.h @@ -3,10 +3,10 @@ #ifdef _DEBUG #undef _DEBUG -#include +#include #define _DEBUG #else -#include +#include #endif #include From 91d59cdb940bfce2670fd3257a1d5c713af461f3 Mon Sep 17 00:00:00 2001 From: fanchy Date: Tue, 22 Oct 2019 20:21:27 +0800 Subject: [PATCH 04/13] fix linux compile error --- pyops_base.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyops_base.h b/pyops_base.h index 29a8ab9..afa7add 100644 --- a/pyops_base.h +++ b/pyops_base.h @@ -4,10 +4,10 @@ #ifdef _DEBUG #undef _DEBUG - #include + #include #define _DEBUG #else - #include + #include #endif #include From a798e5774964ccfafefa34c5bbcdd01de672f52d Mon Sep 17 00:00:00 2001 From: fanchy Date: Tue, 22 Oct 2019 20:24:55 +0800 Subject: [PATCH 05/13] erase std namespace --- example.cpp | 2 +- ffpython.cpp | 22 +++++++++++----------- ffpython.h | 18 +++++++++--------- pyops_for_embed.h | 12 ++++++------ pyops_for_extend.h | 4 ++-- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/example.cpp b/example.cpp index 4ae00e2..2c5bb15 100644 --- a/example.cpp +++ b/example.cpp @@ -5,7 +5,7 @@ #include "ffpython.h" -#define TestGuard(X, Y) printf("-------%s begin-----------\n", X);try {Y;}catch(exception& e_){printf("exception<%s>\n", e_.what());}\ +#define TestGuard(X, Y) printf("-------%s begin-----------\n", X);try {Y;}catch(std::exception& e_){printf("exception<%s>\n", e_.what());}\ printf("-------%s end-----------\n", X); void test_base(ffpython_t& ffpython) diff --git a/ffpython.cpp b/ffpython.cpp index 336ae1c..bfd3561 100644 --- a/ffpython.cpp +++ b/ffpython.cpp @@ -157,7 +157,7 @@ int ffpython_t::reload(const std::string& py_name_) if (NULL == pModule) { pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); + throw std::runtime_error(err_msg.c_str()); return -1; } @@ -166,7 +166,7 @@ int ffpython_t::reload(const std::string& py_name_) if (NULL == pNewMod) { pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); + throw std::runtime_error(err_msg.c_str()); return -1; } Py_DECREF(pNewMod); @@ -183,7 +183,7 @@ int ffpython_t::load(const std::string& py_name_) if (NULL == pModule) { pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); + throw std::runtime_error(err_msg.c_str()); return -1; } @@ -257,7 +257,7 @@ void ffpython_t::rename_method() std::string pystr_args_only_name; for (int j = 0; j < m_func_info[i].args_num; ++j) { - stringstream ss; + std::stringstream ss; if (pystr_args.empty()) { ss << "a" << (j+1); @@ -272,7 +272,7 @@ void ffpython_t::rename_method() pystr_args_only_name = pystr_args; for (int j = 0; j < m_func_info[i].option_args_num; ++j) { - stringstream ss; + std::stringstream ss; if (pystr_args.empty()) { ss << "a" << (m_func_info[i].args_num + j+1); @@ -291,7 +291,7 @@ void ffpython_t::rename_method() if (!pystr_args_only_name.empty()) pystr_args_only_name += ","; - std::ostringstream oss;//创建一个流 + std::stringstream oss;//创建一个流 oss << m_func_info[i].func_addr;//把值传递如流中 std::string funcAddrStr = oss.str();//获取转换后的字符转并将其写入result @@ -435,8 +435,8 @@ void ffpython_t::rename_pyclass() { for (size_t i = 0; i < m_all_pyclass.size(); ++i) { - stringstream str_def_args; - stringstream str_init_args; + std::stringstream str_def_args; + std::stringstream str_init_args; for (int a = 0; a < m_all_pyclass[i].args_num; ++a) { str_def_args << "a" << (a + 1) << ","; @@ -510,7 +510,7 @@ void ffpython_t::rename_pyclass() std::string pystr_args_only_name; for (int j = 0; j < m_all_pyclass[i].methods_info[m].args_num; ++j) { - stringstream ss; + std::stringstream ss; if (pystr_args.empty()) { ss << "a" << (j + 1); @@ -525,7 +525,7 @@ void ffpython_t::rename_pyclass() pystr_args_only_name = pystr_args; for (int j = 0; j < m_all_pyclass[i].methods_info[m].option_args_num; ++j) { - stringstream ss; + std::stringstream ss; if (pystr_args.empty()) { ss << "a" << (m_all_pyclass[i].methods_info[m].args_num + j + 1); @@ -544,7 +544,7 @@ void ffpython_t::rename_pyclass() if (!pystr_args_only_name.empty()) pystr_args_only_name += ","; - std::ostringstream oss;//创建一个流 + std::stringstream oss;//创建一个流 oss << m_all_pyclass[i].methods_info[m].func_addr;//把值传递如流中 std::string funcAddrStr = oss.str();//获取转换后的字符转并将其写入result diff --git a/ffpython.h b/ffpython.h index f2d3807..47bf0ce 100644 --- a/ffpython.h +++ b/ffpython.h @@ -11,7 +11,7 @@ #include #include -using namespace std; + #include "pyops_base.h" #include "pyops_for_embed.h" @@ -73,7 +73,7 @@ class ffpython_t pyclass_regigster_tool_t& reg_class(const std::string& class_name_, std::string doc_ = "", std::string inherit_name_ = "") { if (pyclass_base_info_t::pytype_info.class_name.empty() == false) - throw runtime_error("this type has been registed"); + throw std::runtime_error("this type has been registed"); pyclass_base_info_t::pytype_info.class_name = class_name_; //pyclass_base_info_t::pytype_info.mod_name = m_mod_name; @@ -376,7 +376,7 @@ class ffpython_t if (NULL == pModule) { pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); + throw std::runtime_error(err_msg.c_str()); } pytype_tool_impl_t pyret; @@ -386,13 +386,13 @@ class ffpython_t if (!pvalue) { pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); + throw std::runtime_error(err_msg.c_str()); } if (pyret.parse_value(pvalue)) { Py_XDECREF(pvalue); - throw runtime_error("type invalid"); + throw std::runtime_error("type invalid"); } Py_XDECREF(pvalue); return pyret.get_value(); @@ -410,7 +410,7 @@ class ffpython_t if (NULL == pModule) { pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); + throw std::runtime_error(err_msg.c_str()); } PyObject* pval = pytype_traits_t::pyobj_from_cppobj(val_); @@ -426,7 +426,7 @@ class ffpython_t std::string err_msg; if (NULL == pModule) { - throw runtime_error("getattr object ptr null"); + throw std::runtime_error("getattr object ptr null"); } pytype_tool_impl_t pyret; @@ -435,13 +435,13 @@ class ffpython_t if (!pvalue) { pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); + throw std::runtime_error(err_msg.c_str()); } if (pyret.parse_value(pvalue)) { Py_XDECREF(pvalue); - throw runtime_error("type invalid"); + throw std::runtime_error("type invalid"); } Py_XDECREF(pvalue); return pyret.get_value(); diff --git a/pyops_for_embed.h b/pyops_for_embed.h index b87ebcf..6b8857a 100644 --- a/pyops_for_embed.h +++ b/pyops_for_embed.h @@ -19,7 +19,7 @@ const T& pycall_t::call(const std::string& mod_name_, const std::string& func_na if (NULL == pModule) { pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); + throw std::runtime_error(err_msg.c_str()); return pyret.get_value(); } @@ -28,7 +28,7 @@ const T& pycall_t::call(const std::string& mod_name_, const std::string& func_na if (!err_msg.empty()) { - throw runtime_error(err_msg.c_str()); + throw std::runtime_error(err_msg.c_str()); } return pyret.get_value(); } @@ -39,7 +39,7 @@ const T& pycall_t::call_obj_method(PyObject *pObj, const std::string& func_name_ if (NULL == pObj) { pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); + throw std::runtime_error(err_msg.c_str()); return pyret.get_value(); } @@ -48,7 +48,7 @@ const T& pycall_t::call_obj_method(PyObject *pObj, const std::string& func_name_ if (!err_msg.empty()) { - throw runtime_error(err_msg.c_str()); + throw std::runtime_error(err_msg.c_str()); } return pyret.get_value(); } @@ -60,7 +60,7 @@ const T& pycall_t::call_lambda(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_too if (NULL == pFunc) { err_msg = "can not call null PyObject"; - throw runtime_error(err_msg.c_str()); + throw std::runtime_error(err_msg.c_str()); return pyret.get_value(); } @@ -68,7 +68,7 @@ const T& pycall_t::call_lambda(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_too if (!err_msg.empty()) { - throw runtime_error(err_msg.c_str()); + throw std::runtime_error(err_msg.c_str()); } return pyret.get_value(); } diff --git a/pyops_for_extend.h b/pyops_for_extend.h index 59ec163..94aa693 100644 --- a/pyops_for_extend.h +++ b/pyops_for_extend.h @@ -36,7 +36,7 @@ struct pyext_tool_t { if (m_index >= m_size) { - stringstream ss; + std::stringstream ss; ss << "param num invalid, only["<< m_index + 1 <<"] provided"; PyErr_SetString(PyExc_TypeError, ss.str().c_str()); m_err = true; @@ -46,7 +46,7 @@ struct pyext_tool_t pytype_tool_impl_t ret_tool; if (ret_tool.parse_value(PyTuple_GetItem(m_arg_tuple, m_index))) { - stringstream ss; + std::stringstream ss; ss << "param[" << m_index + 1 << "] type invalid, "<< pytype_traits_t::get_typename() << " needed"; PyErr_SetString(PyExc_TypeError, ss.str().c_str()); m_err = true; From 346f738d50ed5b2abf29197d2601d1e5eba13862 Mon Sep 17 00:00:00 2001 From: fanchy Date: Tue, 22 Oct 2019 20:27:06 +0800 Subject: [PATCH 06/13] add readme for python3 --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cd9a80c..1240fb2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # ffpython +## default use python3 , python2 use files in python2.7 ffpython is a c++ lib,which is to simplify task that embed python and extend python. For example, call python function, register c++ function to python, register c++ class to python. @@ -13,9 +14,8 @@ Only one implement c++ header file. * when python exception throw, ffpython will wrap it as a std exception which includes python traceback info. ## Supported Python versions - * python2.5 python2.6 python2.7, win / linux - * python3.x is being developed, but unfortunately, python3.x api is so different to python2.x, even diffent between python3.2 - and python3.3, Headache!! + * python2.5 python2.6 python2.7 python3, win / linux + ## Embed Python script in C++ ### Get / Set varialbe in python script/module From 05047a7118bac0e98f3c14b097c519be5f59df39 Mon Sep 17 00:00:00 2001 From: fanchy Date: Tue, 22 Oct 2019 20:30:24 +0800 Subject: [PATCH 07/13] mod readme for py3 --- README.md | 78 ++++++++++++++++++++++++++----------------------------- 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 1240fb2..7c4b877 100644 --- a/README.md +++ b/README.md @@ -39,33 +39,7 @@ Only one implement c++ header file. typedef map > > ret_t; ret_t val = ffpython.call("fftest", "test_return_stl"); ``` -## Extend Python -### register c++ static function, all base type supported. Arg num can be nine. -``` c++ -static int print_val(int a1, float a2, const string& a3, const vector& a4) -{ - printf("%s[%d,%f,%s,%d]\n", __FUNCTION__, a1, a2, a3.c_str(), a4.size()); - return 0; -} -struct ops_t -{ - static list return_stl() - { - list ret;ret.push_back(1024); - printf("%s\n", __FUNCTION__); - return ret; - } -}; -void test_reg_function() -{ - ffpython_t ffpython;//("ext1"); - ffpython.reg(&print_val, "print_val") - .reg(&ops_t::return_stl, "return_stl"); - ffpython.init("ext1"); - ffpython.call("fftest", "test_reg_function"); -} -``` ### register c++ class, python can use it just like builtin types. ``` c++ @@ -113,22 +87,7 @@ static foo_t* obj_test(dumy_t* p) return p; } -void test_register_base_class(ffpython_t& ffpython) -{ - ffpython.reg_class("foo_t") - .reg(&foo_t::get_value, "get_value") - .reg(&foo_t::set_value, "set_value") - .reg(&foo_t::test_stl, "test_stl") - .reg_property(&foo_t::m_value, "m_value"); - - ffpython.reg_class("dumy_t", "dumy_t class inherit foo_t ctor ", "foo_t") - .reg(&dumy_t::dump, "dump"); - ffpython.reg(obj_test, "obj_test"); - - ffpython.init("ext2"); - ffpython.call("fftest", "test_register_base_class"); -}; ``` ### Register c++ class which inherit a class having been registered. ``` c++ @@ -147,6 +106,43 @@ void test_cpp_obj_py_obj(ffpython_t& ffpython) foo_t* p = ffpython.call("fftest", "test_cpp_obj_py_obj", &tmp_foo); } +``` +## Extend Python +### register c++ static function, all base type supported. Arg num can be nine. +``` c++ +static int print_val(int a1, float a2, const string& a3, const vector& a4) +{ + printf("%s[%d,%f,%s,%d]\n", __FUNCTION__, a1, a2, a3.c_str(), a4.size()); + return 0; +} +struct ops_t +{ + static list return_stl() + { + list ret;ret.push_back(1024); + printf("%s\n", __FUNCTION__); + return ret; + } +}; + +std::string test_reg_function(ffpython_t& ffpython) +{ + ffpython.reg(&print_val, "print_val") + .reg(&ops_t::return_stl, "return_stl"); + + ffpython.reg_class("foo_t") + .reg(&foo_t::get_value, "get_value") + .reg(&foo_t::set_value, "set_value") + .reg(&foo_t::test_stl, "test_stl") + .reg_property(&foo_t::m_value, "m_value"); + + ffpython.reg_class("dumy_t", "dumy_t class inherit foo_t ctor ", "foo_t") + .reg(&dumy_t::dump, "dump"); + + ffpython.reg(obj_test, "obj_test"); + return "cppext"; +} + ``` ## Python test script ``` python From 2a1bb3576a2a016c499d57823d607f3fb72d18e4 Mon Sep 17 00:00:00 2001 From: fanchy Date: Tue, 22 Oct 2019 20:31:04 +0800 Subject: [PATCH 08/13] mod readme for py3 --- README.md | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 7c4b877..75653cb 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,8 @@ std::string test_reg_function(ffpython_t& ffpython) ``` ## Python test script ``` python + + def test_base(a1, a2, a3): print('test_base', a1, a2, a3) return 0 @@ -161,14 +163,15 @@ def test_return_stl(): return ret def test_reg_function(): - import ext1 - ext1.print_val(123, 45.6 , "----789---", [3.14]) - ret = ext1.return_stl() + import cppext + cppext.print_val(123, 45.6 , "----789---", [3.14]) + ret = cppext.return_stl() print('test_reg_function', ret) def test_register_base_class(): - import ext2 - foo = ext2.foo_t(20130426) + import cppext + foo = cppext.foo_t(20130426) + print("test_register_base_class get_val:", foo.get_value()) foo.set_value(778899) print("test_register_base_class get_val:", foo.get_value(), foo.m_value) @@ -176,8 +179,8 @@ def test_register_base_class(): print('test_register_base_class test_register_base_class', foo) def test_register_inherit_class(): - import ext2 - dumy = ext2.dumy_t(20130426) + import cppext + dumy = cppext.dumy_t(20130426) print("test_register_inherit_class get_val:", dumy.get_value()) dumy.set_value(778899) print("test_register_inherit_class get_val:", dumy.get_value(), dumy.m_value) @@ -185,26 +188,44 @@ def test_register_inherit_class(): dumy.dump() print('test_register_inherit_class', dumy) +def test_cpp_obj_to_py_ext(foo): + print('test_cpp_obj_to_py_ext', len(foo)) + for k in range(0, len(foo)): + print('test_cpp_obj_to_py_ext', k, foo[k].m_value) + def test_cpp_obj_to_py(foo): - import ext2 + import cppext print("test_cpp_obj_to_py get_val:", foo.get_value()) foo.set_value(778899) print("test_cpp_obj_to_py get_val:", foo.get_value(), foo.m_value) foo.test_stl({"key": [11,22,33] }) + foo.m_value = 100 print('test_cpp_obj_to_py test_register_base_class', foo) def test_cpp_obj_py_obj(dumy): - import ext2 + import cppext print("test_cpp_obj_py_obj get_val:", dumy.get_value()) dumy.set_value(778899) print("test_cpp_obj_py_obj get_val:", dumy.get_value(), dumy.m_value) dumy.test_stl({"key": [11,22,33] }) dumy.dump() - ext2.obj_test(dumy) + cppext.obj_test(dumy) print('test_cpp_obj_py_obj', dumy) return dumy +class pyclass_t: + def __init__(self): + print('pyclass_t init....') + def sayHi(self, a1, a2): + print('sayHi..', a1, a2) +def test_cpp_obj_return_py_obj(): + return pyclass_t() +def test_cpp_obj_return_py_lambda(): + def test_lambda(a1): + print('test_lambda....', a1) + return test_lambda + ``` ## Summary From 31f93963a00e4aa834e3fec53d0aa7b622594d1b Mon Sep 17 00:00:00 2001 From: fanchy Date: Wed, 17 Jun 2020 14:22:12 +0800 Subject: [PATCH 09/13] move oldfiles --- .../python2.7}/VersionForRead/ffpython.cpp | 1136 +++--- .../python2.7}/VersionForRead/ffpython.h | 962 ++--- .../python2.7}/VersionForRead/pyops_base.h | 2246 +++++------ .../VersionForRead/pyops_for_embed.h | 154 +- .../VersionForRead/pyops_for_extend.h | 3490 ++++++++--------- .../python2.7}/ffpython.h | 0 6 files changed, 3994 insertions(+), 3994 deletions(-) rename {python2.7 => oldversion/python2.7}/VersionForRead/ffpython.cpp (97%) rename {python2.7 => oldversion/python2.7}/VersionForRead/ffpython.h (97%) rename {python2.7 => oldversion/python2.7}/VersionForRead/pyops_base.h (96%) rename {python2.7 => oldversion/python2.7}/VersionForRead/pyops_for_embed.h (95%) rename {python2.7 => oldversion/python2.7}/VersionForRead/pyops_for_extend.h (97%) rename {python2.7 => oldversion/python2.7}/ffpython.h (100%) diff --git a/python2.7/VersionForRead/ffpython.cpp b/oldversion/python2.7/VersionForRead/ffpython.cpp similarity index 97% rename from python2.7/VersionForRead/ffpython.cpp rename to oldversion/python2.7/VersionForRead/ffpython.cpp index c78bf09..fee25ca 100644 --- a/python2.7/VersionForRead/ffpython.cpp +++ b/oldversion/python2.7/VersionForRead/ffpython.cpp @@ -1,568 +1,568 @@ -#include "ffpython.h" - - -//! 获取python异常信息 - -int pyops_t::traceback(string& ret_) -{ - PyObject* err = PyErr_Occurred(); - - if (err != NULL) { - PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL; - PyObject *pyth_module = NULL, *pyth_func = NULL; - - PyErr_Fetch(&ptype, &pvalue, &ptraceback); - if (pvalue) - { - if (true == PyList_Check(pvalue)) - { - int n = PyList_Size(pvalue); - for (int i = 0; i < n; ++i) - { - PyObject *pystr = PyObject_Str(PyList_GetItem(pvalue, i)); - ret_ += PyString_AsString(pystr); - ret_ += "\n"; - Py_DECREF(pystr); - } - } - if (true == PyTuple_Check(pvalue)) - { - int n = PyTuple_Size(pvalue); - for (int i = 0; i < n; ++i) - { - PyObject* tmp_str = PyTuple_GetItem(pvalue, i); - if (true == PyTuple_Check(tmp_str)) - { - int m = PyTuple_Size(tmp_str); - for (int j = 0; j < m; ++j) - { - PyObject *pystr = PyObject_Str(PyTuple_GetItem(tmp_str, j)); - ret_ += PyString_AsString(pystr); - ret_ += ","; - Py_DECREF(pystr); - } - } - else - { - PyObject *pystr = PyObject_Str(tmp_str); - ret_ += PyString_AsString(pystr); - Py_DECREF(pystr); - } - ret_ += "\n"; - } - } - else - { - PyObject *pystr = PyObject_Str(pvalue); - if (pystr) - { - ret_ += PyString_AsString(pystr); - ret_ += "\n"; - Py_DECREF(pystr); - } - } - } - - /* See if we can get a full traceback */ - PyObject *module_name = PyString_FromString("traceback"); - pyth_module = PyImport_Import(module_name); - Py_DECREF(module_name); - - if (pyth_module && ptype && pvalue && ptraceback) - { - pyth_func = PyObject_GetAttrString(pyth_module, "format_exception"); - if (pyth_func && PyCallable_Check(pyth_func)) { - PyObject *pyth_val = PyObject_CallFunctionObjArgs(pyth_func, ptype, pvalue, ptraceback, NULL); - if (pyth_val && true == PyList_Check(pyth_val)) - { - int n = PyList_Size(pyth_val); - for (int i = 0; i < n; ++i) - { - PyObject* tmp_str = PyList_GetItem(pyth_val, i); - PyObject *pystr = PyObject_Str(tmp_str); - if (pystr) - { - ret_ += PyString_AsString(pystr); - - Py_DECREF(pystr); - } - ret_ += "\n"; - } - } - Py_XDECREF(pyth_val); - } - } - Py_XDECREF(pyth_func); - Py_XDECREF(pyth_module); - Py_XDECREF(ptype); - Py_XDECREF(pvalue); - Py_XDECREF(ptraceback); - PyErr_Clear(); - return 0; - } - - return -1; -} - - -ffpython_t::ffpython_t() -{ - if (!Py_IsInitialized()) - Py_Initialize(); -} -ffpython_t::~ffpython_t() -{ - clear_cache_pyobject(); -} - - -int ffpython_t::init_py() -{ - Py_Initialize(); - return 0; -} -int ffpython_t::final_py() -{ - Py_Finalize(); - return 0; -} - -int ffpython_t::add_path(const string& path_) -{ - char buff[1024]; - SAFE_SPRINTF(buff, sizeof(buff), "import sys\nif '%s' not in sys.path:\n\tsys.path.append('%s')\n", path_.c_str(), path_.c_str()); - PyRun_SimpleString(buff); - return 0; -} - -int ffpython_t::run_string(const string& py_) -{ - PyRun_SimpleString(py_.c_str()); - return 0; -} - -int ffpython_t::reload(const string& py_name_) -{ - PyObject *pName = NULL, *pModule = NULL; - string err_msg; - - pName = PyString_FromString(py_name_.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - return -1; - } - - PyObject *pNewMod = PyImport_ReloadModule(pModule); - Py_DECREF(pModule); - if (NULL == pNewMod) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - return -1; - } - Py_DECREF(pNewMod); - return 0; -} -int ffpython_t::load(const string& py_name_) -{ - PyObject *pName = NULL, *pModule = NULL; - string err_msg; - - pName = PyString_FromString(py_name_.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - return -1; - } - - Py_DECREF(pModule); - return 0; -} - -int ffpython_t::init(const string& mod_name_, string doc_) -{ - m_mod_name = mod_name_; - m_mod_doc = doc_; - PyObject* m = init_method(); - init_pyclass(m); - return 0; -} - -PyObject* ffpython_t::init_method() -{ - string mod_name_ = m_mod_name; - string doc_ = m_mod_doc; - - if (m_pymethod_defs.empty()) - { - m_pymethod_defs.reserve(m_func_info.size() + 1); - - for (size_t i = 0; i < m_func_info.size(); ++i) - { - PyMethodDef tmp = {m_func_info[i].func_impl_name.c_str(), m_func_info[i].func, - METH_VARARGS, m_func_info[i].doc_impl.c_str()}; - m_pymethod_defs.push_back(tmp); - } - PyMethodDef tmp = {NULL}; - m_pymethod_defs.push_back(tmp); - } - - PyObject* m = Py_InitModule3(m_mod_name.c_str(), &(m_pymethod_defs.front()), doc_.c_str()); - - for (size_t i = 0; i < m_func_info.size(); ++i) - { - string pystr_args; - string pystr_args_only_name; - for (int j = 0; j < m_func_info[i].args_num; ++j) - { - stringstream ss; - if (pystr_args.empty()) - { - ss << "a" << (j+1); - pystr_args += ss.str(); - } - else - { - ss << ", a" << (j+1); - pystr_args += ss.str(); - } - } - pystr_args_only_name = pystr_args; - for (int j = 0; j < m_func_info[i].option_args_num; ++j) - { - stringstream ss; - if (pystr_args.empty()) - { - ss << "a" << (m_func_info[i].args_num + j+1); - string tmp = ss.str(); - pystr_args_only_name += tmp; - pystr_args += tmp + " = None"; - } - else - { - ss << ", a" << (m_func_info[i].args_num + j+1); - string tmp = ss.str(); - pystr_args_only_name += tmp; - pystr_args += tmp + " = None"; - } - } - if (!pystr_args_only_name.empty()) - pystr_args_only_name += ","; - - char buff[1024]; - SAFE_SPRINTF(buff, sizeof(buff), - "_tmp_ff_ = None\nif '%s' in globals():\n\t_tmp_ff_ = globals()['%s']\n" - "def %s(%s):\n" - "\t'''%s'''\n" - "\treturn %s.%s(%ld,(%s))\n" - "import %s\n" - "%s.%s = %s\n" - "%s = None\n" - "if _tmp_ff_:\n\tglobals()['%s'] = _tmp_ff_\n_tmp_ff_ = None\n", - m_func_info[i].func_name.c_str(), m_func_info[i].func_name.c_str(), - m_func_info[i].func_name.c_str(), pystr_args.c_str(), - m_func_info[i].doc.c_str(), - m_mod_name.c_str(), m_func_info[i].func_impl_name.c_str(), m_func_info[i].func_addr, pystr_args_only_name.c_str(), - m_mod_name.c_str(), - m_mod_name.c_str(), m_func_info[i].func_name.c_str(), m_func_info[i].func_name.c_str(), - m_func_info[i].func_name.c_str(), - m_func_info[i].func_name.c_str() - ); - - //printf(buff); - PyRun_SimpleString(buff); - } - - return m; -} - -int ffpython_t::init_pyclass(PyObject* m) -{ - for (size_t i = 0; i < m_all_pyclass.size(); ++i) - { - m_all_pyclass[i].static_pytype_info->mod_name = m_mod_name; - if (false == m_all_pyclass[i].inherit_name.empty()) - { - pyclass_regigster_tool_t* inherit_class = get_pyclass_info_by_name(m_all_pyclass[i].inherit_name); - assert(inherit_class && "base class must be registed"); - for (size_t n = 0; n < inherit_class->methods_info.size(); ++n) - { - const string& method_name = inherit_class->methods_info[n].func_name; - if (false == is_method_exist(m_all_pyclass[i].methods_info, method_name)) - { - m_all_pyclass[i].methods_info.push_back(inherit_class->methods_info[n]); - } - } - for (size_t n = 0; n < inherit_class->propertys_info.size(); ++n) - { - const string& property_name = inherit_class->propertys_info[n].property_name; - if (false == is_property_exist(m_all_pyclass[i].propertys_info, property_name)) - { - m_all_pyclass[i].propertys_info.push_back(inherit_class->propertys_info[n]); - } - } - } - //! init class property - for (size_t j = 0; j < m_all_pyclass[i].propertys_info.size(); ++j) - { - PyGetSetDef tmp = {(char*)m_all_pyclass[i].propertys_info[j].property_name.c_str(), - m_all_pyclass[i].propertys_info[j].getter_func, - m_all_pyclass[i].propertys_info[j].setter_func, - (char*)m_all_pyclass[i].propertys_info[j].doc.c_str(), - m_all_pyclass[i].propertys_info[j].ptr - }; - m_all_pyclass[i].pyproperty_def.push_back(tmp); - } - PyGetSetDef tmp_property_def = {NULL}; - m_all_pyclass[i].pyproperty_def.push_back(tmp_property_def); - //! init class method - for (size_t j = 0; j < m_all_pyclass[i].methods_info.size(); ++j) - { - PyMethodDef tmp = {m_all_pyclass[i].methods_info[j].func_real_name.c_str(), - m_all_pyclass[i].methods_info[j].func, - METH_VARARGS, - m_all_pyclass[i].methods_info[j].doc.c_str() - }; - m_all_pyclass[i].pymethod_def.push_back(tmp); - - } - PyMethodDef tmp_del = {"delete", - m_all_pyclass[i].delete_func, - METH_VARARGS, - "delete obj" - }; - m_all_pyclass[i].pymethod_def.push_back(tmp_del); - PyMethodDef tmp_method_def = {NULL}; - m_all_pyclass[i].pymethod_def.push_back(tmp_method_def); - - m_all_pyclass[i].class_name_with_mod = m_mod_name + "." + m_all_pyclass[i].class_name; - m_all_pyclass[i].class_reel_name_with_mod = m_mod_name + "." + m_all_pyclass[i].class_real_name; - - PyTypeObject tmp_pytype_def = - { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - m_all_pyclass[i].class_reel_name_with_mod.c_str(), /*tp_name*/ - m_all_pyclass[i].type_size, /*tp_size*/ - 0, /*tp_itemsize*/ - (destructor)m_all_pyclass[i].dector, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - m_all_pyclass[i].doc.c_str(), /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - &(m_all_pyclass[i].pymethod_def.front()),//Noddy_methods, /* tp_methods */ - 0,//Noddy_members, /* tp_members */ - &(m_all_pyclass[i].pyproperty_def.front()),//Noddy_getseters, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)m_all_pyclass[i].init, /* tp_init */ - 0, /* tp_alloc */ - m_all_pyclass[i].ctor, /* tp_new */ - }; - m_all_pyclass[i].pytype_def = tmp_pytype_def; - m_all_pyclass[i].static_pytype_info->pytype_def = &m_all_pyclass[i].pytype_def; - cpp_to_pyclass_reg_info_t::add(m_all_pyclass[i].class_name, m_all_pyclass[i].inherit_name, &m_all_pyclass[i].pytype_def); - - if (PyType_Ready(&(m_all_pyclass[i].pytype_def)) < 0) - return -1; - PyObject* tmpP = (PyObject*)(&(m_all_pyclass[i].pytype_def)); - Py_INCREF(tmpP); - PyModule_AddObject(m, m_all_pyclass[i].class_real_name.c_str(), (PyObject *)&m_all_pyclass[i].pytype_def); - - stringstream str_def_args; - stringstream str_init_args; - for (int a = 0; a < m_all_pyclass[i].args_num; ++a) - { - str_def_args << "a"<<(a+1)<<","; - str_init_args << "a"<<(a+1)<<","; - } - for (int b = 0; b < m_all_pyclass[b].option_args_num; ++b) - { - str_def_args << "a"<<(m_all_pyclass[i].args_num+ b+1)<<" = None,"; - str_init_args << "a"<<(m_all_pyclass[i].args_num+ b+1)<<","; - } - - char buff[1024]; - SAFE_SPRINTF(buff, sizeof(buff), - "_tmp_ff_ = None\nif '%s' in globals():\n\t_tmp_ff_ = globals()['%s']\n" - "import %s\n" - "class %s(object):\n" - "\t'''%s'''\n" - "\tdef __init__(self, %s assign_obj_ = 0):\n"//! ����init���� - "\t\t'''%s'''\n" - "\t\tif True == isinstance(assign_obj_, %s):\n" - "\t\t\tself.obj = assign_obj_\n" - "\t\t\treturn\n" - "\t\tself.obj = %s(0,(%s))\n", - m_all_pyclass[i].class_name.c_str(), m_all_pyclass[i].class_name.c_str(), - m_mod_name.c_str(), - m_all_pyclass[i].class_name.c_str(), - m_all_pyclass[i].doc.c_str(), - str_def_args.str().c_str(), - "init class", - m_all_pyclass[i].class_reel_name_with_mod.c_str(), - m_all_pyclass[i].class_reel_name_with_mod.c_str(), str_init_args.str().c_str() - ); - - string gen_class_str = buff; - SAFE_SPRINTF(buff, sizeof(buff), - "\tdef delete(self):\n" - "\t\t'''delete obj'''\n" - "\t\tself.obj.delete()\n"); - gen_class_str += buff; - //! 增加析构函数 - //! 增加属性 - for (size_t c = 0; c < m_all_pyclass[i].propertys_info.size(); ++c) - { - SAFE_SPRINTF(buff, sizeof(buff), - "\tdef get_%s(self):\n" - "\t\treturn self.obj.%s\n" - "\tdef set_%s(self, v):\n" - "\t\tself.obj.%s = v\n" - "\t@property\n" - "\tdef %s(self):\n" - "\t\treturn self.obj.%s\n" - "\t@%s.setter\n" - "\tdef %s(self, v):\n" - "\t\tself.obj.%s = v\n", - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str() - ); - gen_class_str += buff; - } - - for (size_t m = 0; m < m_all_pyclass[i].methods_info.size(); ++m) - { - string pystr_args; - string pystr_args_only_name; - for (int j = 0; j < m_all_pyclass[i].methods_info[m].args_num; ++j) - { - stringstream ss; - if (pystr_args.empty()) - { - ss << "a" << (j+1); - pystr_args += ss.str(); - } - else - { - ss << ", a" << (j+1); - pystr_args += ss.str(); - } - } - pystr_args_only_name = pystr_args; - for (int j = 0; j < m_all_pyclass[i].methods_info[m].option_args_num; ++j) - { - stringstream ss; - if (pystr_args.empty()) - { - ss << "a" << (m_all_pyclass[i].methods_info[m].args_num + j+1); - string tmp = ss.str(); - pystr_args_only_name += tmp; - pystr_args += tmp + " = None"; - } - else - { - ss << ", a" << (m_all_pyclass[i].methods_info[m].args_num + j+1); - string tmp = ss.str(); - pystr_args_only_name += tmp; - pystr_args += tmp + " = None"; - } - } - if (!pystr_args_only_name.empty()) - pystr_args_only_name += ","; - - SAFE_SPRINTF(buff, sizeof(buff), - "\tdef %s(self,%s):\n" - "\t\t'''%s'''\n" - "\t\treturn self.obj.%s(%ld,(%s))\n" - ,m_all_pyclass[i].methods_info[m].func_name.c_str(), pystr_args.c_str(), - m_all_pyclass[i].methods_info[m].doc.c_str(), - m_all_pyclass[i].methods_info[m].func_real_name.c_str(), m_all_pyclass[i].methods_info[m].func_addr, pystr_args_only_name.c_str() - ); - gen_class_str += buff; - } - SAFE_SPRINTF(buff, sizeof(buff), - "%s.%s = %s\n" - "%s = None\n" - "if _tmp_ff_:\n\tglobals()['%s'] = _tmp_ff_\n_tmp_ff_ = None\n", - m_mod_name.c_str(), m_all_pyclass[i].class_name.c_str(), m_all_pyclass[i].class_name.c_str(), - m_all_pyclass[i].class_name.c_str(), - m_all_pyclass[i].class_name.c_str() - ); - gen_class_str += buff; - //printf(gen_class_str.c_str()); - PyRun_SimpleString(gen_class_str.c_str()); - } - return 0; -} - - -bool ffpython_t::is_method_exist(const vector& src_, const string& new_) -{ - for (size_t i = 0; i < src_.size(); ++i) - { - if (new_ == src_[i].func_name) - { - return true; - } - } - return false; -} -bool ffpython_t::is_property_exist(const vector& src_, const string& new_) -{ - for (size_t i = 0; i < src_.size(); ++i) - { - if (new_ == src_[i].property_name) - { - return true; - } - } - return false; -} -pyclass_regigster_tool_t* ffpython_t::get_pyclass_info_by_name(const string& name_) -{ - for (size_t i = 0; i < m_all_pyclass.size(); ++i) - { - if (m_all_pyclass[i].class_name == name_) - { - return &(m_all_pyclass[i]); - } - } - return NULL; -} - +#include "ffpython.h" + + +//! 获取python异常信息 + +int pyops_t::traceback(string& ret_) +{ + PyObject* err = PyErr_Occurred(); + + if (err != NULL) { + PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL; + PyObject *pyth_module = NULL, *pyth_func = NULL; + + PyErr_Fetch(&ptype, &pvalue, &ptraceback); + if (pvalue) + { + if (true == PyList_Check(pvalue)) + { + int n = PyList_Size(pvalue); + for (int i = 0; i < n; ++i) + { + PyObject *pystr = PyObject_Str(PyList_GetItem(pvalue, i)); + ret_ += PyString_AsString(pystr); + ret_ += "\n"; + Py_DECREF(pystr); + } + } + if (true == PyTuple_Check(pvalue)) + { + int n = PyTuple_Size(pvalue); + for (int i = 0; i < n; ++i) + { + PyObject* tmp_str = PyTuple_GetItem(pvalue, i); + if (true == PyTuple_Check(tmp_str)) + { + int m = PyTuple_Size(tmp_str); + for (int j = 0; j < m; ++j) + { + PyObject *pystr = PyObject_Str(PyTuple_GetItem(tmp_str, j)); + ret_ += PyString_AsString(pystr); + ret_ += ","; + Py_DECREF(pystr); + } + } + else + { + PyObject *pystr = PyObject_Str(tmp_str); + ret_ += PyString_AsString(pystr); + Py_DECREF(pystr); + } + ret_ += "\n"; + } + } + else + { + PyObject *pystr = PyObject_Str(pvalue); + if (pystr) + { + ret_ += PyString_AsString(pystr); + ret_ += "\n"; + Py_DECREF(pystr); + } + } + } + + /* See if we can get a full traceback */ + PyObject *module_name = PyString_FromString("traceback"); + pyth_module = PyImport_Import(module_name); + Py_DECREF(module_name); + + if (pyth_module && ptype && pvalue && ptraceback) + { + pyth_func = PyObject_GetAttrString(pyth_module, "format_exception"); + if (pyth_func && PyCallable_Check(pyth_func)) { + PyObject *pyth_val = PyObject_CallFunctionObjArgs(pyth_func, ptype, pvalue, ptraceback, NULL); + if (pyth_val && true == PyList_Check(pyth_val)) + { + int n = PyList_Size(pyth_val); + for (int i = 0; i < n; ++i) + { + PyObject* tmp_str = PyList_GetItem(pyth_val, i); + PyObject *pystr = PyObject_Str(tmp_str); + if (pystr) + { + ret_ += PyString_AsString(pystr); + + Py_DECREF(pystr); + } + ret_ += "\n"; + } + } + Py_XDECREF(pyth_val); + } + } + Py_XDECREF(pyth_func); + Py_XDECREF(pyth_module); + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + PyErr_Clear(); + return 0; + } + + return -1; +} + + +ffpython_t::ffpython_t() +{ + if (!Py_IsInitialized()) + Py_Initialize(); +} +ffpython_t::~ffpython_t() +{ + clear_cache_pyobject(); +} + + +int ffpython_t::init_py() +{ + Py_Initialize(); + return 0; +} +int ffpython_t::final_py() +{ + Py_Finalize(); + return 0; +} + +int ffpython_t::add_path(const string& path_) +{ + char buff[1024]; + SAFE_SPRINTF(buff, sizeof(buff), "import sys\nif '%s' not in sys.path:\n\tsys.path.append('%s')\n", path_.c_str(), path_.c_str()); + PyRun_SimpleString(buff); + return 0; +} + +int ffpython_t::run_string(const string& py_) +{ + PyRun_SimpleString(py_.c_str()); + return 0; +} + +int ffpython_t::reload(const string& py_name_) +{ + PyObject *pName = NULL, *pModule = NULL; + string err_msg; + + pName = PyString_FromString(py_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return -1; + } + + PyObject *pNewMod = PyImport_ReloadModule(pModule); + Py_DECREF(pModule); + if (NULL == pNewMod) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return -1; + } + Py_DECREF(pNewMod); + return 0; +} +int ffpython_t::load(const string& py_name_) +{ + PyObject *pName = NULL, *pModule = NULL; + string err_msg; + + pName = PyString_FromString(py_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return -1; + } + + Py_DECREF(pModule); + return 0; +} + +int ffpython_t::init(const string& mod_name_, string doc_) +{ + m_mod_name = mod_name_; + m_mod_doc = doc_; + PyObject* m = init_method(); + init_pyclass(m); + return 0; +} + +PyObject* ffpython_t::init_method() +{ + string mod_name_ = m_mod_name; + string doc_ = m_mod_doc; + + if (m_pymethod_defs.empty()) + { + m_pymethod_defs.reserve(m_func_info.size() + 1); + + for (size_t i = 0; i < m_func_info.size(); ++i) + { + PyMethodDef tmp = {m_func_info[i].func_impl_name.c_str(), m_func_info[i].func, + METH_VARARGS, m_func_info[i].doc_impl.c_str()}; + m_pymethod_defs.push_back(tmp); + } + PyMethodDef tmp = {NULL}; + m_pymethod_defs.push_back(tmp); + } + + PyObject* m = Py_InitModule3(m_mod_name.c_str(), &(m_pymethod_defs.front()), doc_.c_str()); + + for (size_t i = 0; i < m_func_info.size(); ++i) + { + string pystr_args; + string pystr_args_only_name; + for (int j = 0; j < m_func_info[i].args_num; ++j) + { + stringstream ss; + if (pystr_args.empty()) + { + ss << "a" << (j+1); + pystr_args += ss.str(); + } + else + { + ss << ", a" << (j+1); + pystr_args += ss.str(); + } + } + pystr_args_only_name = pystr_args; + for (int j = 0; j < m_func_info[i].option_args_num; ++j) + { + stringstream ss; + if (pystr_args.empty()) + { + ss << "a" << (m_func_info[i].args_num + j+1); + string tmp = ss.str(); + pystr_args_only_name += tmp; + pystr_args += tmp + " = None"; + } + else + { + ss << ", a" << (m_func_info[i].args_num + j+1); + string tmp = ss.str(); + pystr_args_only_name += tmp; + pystr_args += tmp + " = None"; + } + } + if (!pystr_args_only_name.empty()) + pystr_args_only_name += ","; + + char buff[1024]; + SAFE_SPRINTF(buff, sizeof(buff), + "_tmp_ff_ = None\nif '%s' in globals():\n\t_tmp_ff_ = globals()['%s']\n" + "def %s(%s):\n" + "\t'''%s'''\n" + "\treturn %s.%s(%ld,(%s))\n" + "import %s\n" + "%s.%s = %s\n" + "%s = None\n" + "if _tmp_ff_:\n\tglobals()['%s'] = _tmp_ff_\n_tmp_ff_ = None\n", + m_func_info[i].func_name.c_str(), m_func_info[i].func_name.c_str(), + m_func_info[i].func_name.c_str(), pystr_args.c_str(), + m_func_info[i].doc.c_str(), + m_mod_name.c_str(), m_func_info[i].func_impl_name.c_str(), m_func_info[i].func_addr, pystr_args_only_name.c_str(), + m_mod_name.c_str(), + m_mod_name.c_str(), m_func_info[i].func_name.c_str(), m_func_info[i].func_name.c_str(), + m_func_info[i].func_name.c_str(), + m_func_info[i].func_name.c_str() + ); + + //printf(buff); + PyRun_SimpleString(buff); + } + + return m; +} + +int ffpython_t::init_pyclass(PyObject* m) +{ + for (size_t i = 0; i < m_all_pyclass.size(); ++i) + { + m_all_pyclass[i].static_pytype_info->mod_name = m_mod_name; + if (false == m_all_pyclass[i].inherit_name.empty()) + { + pyclass_regigster_tool_t* inherit_class = get_pyclass_info_by_name(m_all_pyclass[i].inherit_name); + assert(inherit_class && "base class must be registed"); + for (size_t n = 0; n < inherit_class->methods_info.size(); ++n) + { + const string& method_name = inherit_class->methods_info[n].func_name; + if (false == is_method_exist(m_all_pyclass[i].methods_info, method_name)) + { + m_all_pyclass[i].methods_info.push_back(inherit_class->methods_info[n]); + } + } + for (size_t n = 0; n < inherit_class->propertys_info.size(); ++n) + { + const string& property_name = inherit_class->propertys_info[n].property_name; + if (false == is_property_exist(m_all_pyclass[i].propertys_info, property_name)) + { + m_all_pyclass[i].propertys_info.push_back(inherit_class->propertys_info[n]); + } + } + } + //! init class property + for (size_t j = 0; j < m_all_pyclass[i].propertys_info.size(); ++j) + { + PyGetSetDef tmp = {(char*)m_all_pyclass[i].propertys_info[j].property_name.c_str(), + m_all_pyclass[i].propertys_info[j].getter_func, + m_all_pyclass[i].propertys_info[j].setter_func, + (char*)m_all_pyclass[i].propertys_info[j].doc.c_str(), + m_all_pyclass[i].propertys_info[j].ptr + }; + m_all_pyclass[i].pyproperty_def.push_back(tmp); + } + PyGetSetDef tmp_property_def = {NULL}; + m_all_pyclass[i].pyproperty_def.push_back(tmp_property_def); + //! init class method + for (size_t j = 0; j < m_all_pyclass[i].methods_info.size(); ++j) + { + PyMethodDef tmp = {m_all_pyclass[i].methods_info[j].func_real_name.c_str(), + m_all_pyclass[i].methods_info[j].func, + METH_VARARGS, + m_all_pyclass[i].methods_info[j].doc.c_str() + }; + m_all_pyclass[i].pymethod_def.push_back(tmp); + + } + PyMethodDef tmp_del = {"delete", + m_all_pyclass[i].delete_func, + METH_VARARGS, + "delete obj" + }; + m_all_pyclass[i].pymethod_def.push_back(tmp_del); + PyMethodDef tmp_method_def = {NULL}; + m_all_pyclass[i].pymethod_def.push_back(tmp_method_def); + + m_all_pyclass[i].class_name_with_mod = m_mod_name + "." + m_all_pyclass[i].class_name; + m_all_pyclass[i].class_reel_name_with_mod = m_mod_name + "." + m_all_pyclass[i].class_real_name; + + PyTypeObject tmp_pytype_def = + { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + m_all_pyclass[i].class_reel_name_with_mod.c_str(), /*tp_name*/ + m_all_pyclass[i].type_size, /*tp_size*/ + 0, /*tp_itemsize*/ + (destructor)m_all_pyclass[i].dector, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + m_all_pyclass[i].doc.c_str(), /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + &(m_all_pyclass[i].pymethod_def.front()),//Noddy_methods, /* tp_methods */ + 0,//Noddy_members, /* tp_members */ + &(m_all_pyclass[i].pyproperty_def.front()),//Noddy_getseters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)m_all_pyclass[i].init, /* tp_init */ + 0, /* tp_alloc */ + m_all_pyclass[i].ctor, /* tp_new */ + }; + m_all_pyclass[i].pytype_def = tmp_pytype_def; + m_all_pyclass[i].static_pytype_info->pytype_def = &m_all_pyclass[i].pytype_def; + cpp_to_pyclass_reg_info_t::add(m_all_pyclass[i].class_name, m_all_pyclass[i].inherit_name, &m_all_pyclass[i].pytype_def); + + if (PyType_Ready(&(m_all_pyclass[i].pytype_def)) < 0) + return -1; + PyObject* tmpP = (PyObject*)(&(m_all_pyclass[i].pytype_def)); + Py_INCREF(tmpP); + PyModule_AddObject(m, m_all_pyclass[i].class_real_name.c_str(), (PyObject *)&m_all_pyclass[i].pytype_def); + + stringstream str_def_args; + stringstream str_init_args; + for (int a = 0; a < m_all_pyclass[i].args_num; ++a) + { + str_def_args << "a"<<(a+1)<<","; + str_init_args << "a"<<(a+1)<<","; + } + for (int b = 0; b < m_all_pyclass[b].option_args_num; ++b) + { + str_def_args << "a"<<(m_all_pyclass[i].args_num+ b+1)<<" = None,"; + str_init_args << "a"<<(m_all_pyclass[i].args_num+ b+1)<<","; + } + + char buff[1024]; + SAFE_SPRINTF(buff, sizeof(buff), + "_tmp_ff_ = None\nif '%s' in globals():\n\t_tmp_ff_ = globals()['%s']\n" + "import %s\n" + "class %s(object):\n" + "\t'''%s'''\n" + "\tdef __init__(self, %s assign_obj_ = 0):\n"//! ����init���� + "\t\t'''%s'''\n" + "\t\tif True == isinstance(assign_obj_, %s):\n" + "\t\t\tself.obj = assign_obj_\n" + "\t\t\treturn\n" + "\t\tself.obj = %s(0,(%s))\n", + m_all_pyclass[i].class_name.c_str(), m_all_pyclass[i].class_name.c_str(), + m_mod_name.c_str(), + m_all_pyclass[i].class_name.c_str(), + m_all_pyclass[i].doc.c_str(), + str_def_args.str().c_str(), + "init class", + m_all_pyclass[i].class_reel_name_with_mod.c_str(), + m_all_pyclass[i].class_reel_name_with_mod.c_str(), str_init_args.str().c_str() + ); + + string gen_class_str = buff; + SAFE_SPRINTF(buff, sizeof(buff), + "\tdef delete(self):\n" + "\t\t'''delete obj'''\n" + "\t\tself.obj.delete()\n"); + gen_class_str += buff; + //! 增加析构函数 + //! 增加属性 + for (size_t c = 0; c < m_all_pyclass[i].propertys_info.size(); ++c) + { + SAFE_SPRINTF(buff, sizeof(buff), + "\tdef get_%s(self):\n" + "\t\treturn self.obj.%s\n" + "\tdef set_%s(self, v):\n" + "\t\tself.obj.%s = v\n" + "\t@property\n" + "\tdef %s(self):\n" + "\t\treturn self.obj.%s\n" + "\t@%s.setter\n" + "\tdef %s(self, v):\n" + "\t\tself.obj.%s = v\n", + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str(), + m_all_pyclass[i].propertys_info[c].property_name.c_str() + ); + gen_class_str += buff; + } + + for (size_t m = 0; m < m_all_pyclass[i].methods_info.size(); ++m) + { + string pystr_args; + string pystr_args_only_name; + for (int j = 0; j < m_all_pyclass[i].methods_info[m].args_num; ++j) + { + stringstream ss; + if (pystr_args.empty()) + { + ss << "a" << (j+1); + pystr_args += ss.str(); + } + else + { + ss << ", a" << (j+1); + pystr_args += ss.str(); + } + } + pystr_args_only_name = pystr_args; + for (int j = 0; j < m_all_pyclass[i].methods_info[m].option_args_num; ++j) + { + stringstream ss; + if (pystr_args.empty()) + { + ss << "a" << (m_all_pyclass[i].methods_info[m].args_num + j+1); + string tmp = ss.str(); + pystr_args_only_name += tmp; + pystr_args += tmp + " = None"; + } + else + { + ss << ", a" << (m_all_pyclass[i].methods_info[m].args_num + j+1); + string tmp = ss.str(); + pystr_args_only_name += tmp; + pystr_args += tmp + " = None"; + } + } + if (!pystr_args_only_name.empty()) + pystr_args_only_name += ","; + + SAFE_SPRINTF(buff, sizeof(buff), + "\tdef %s(self,%s):\n" + "\t\t'''%s'''\n" + "\t\treturn self.obj.%s(%ld,(%s))\n" + ,m_all_pyclass[i].methods_info[m].func_name.c_str(), pystr_args.c_str(), + m_all_pyclass[i].methods_info[m].doc.c_str(), + m_all_pyclass[i].methods_info[m].func_real_name.c_str(), m_all_pyclass[i].methods_info[m].func_addr, pystr_args_only_name.c_str() + ); + gen_class_str += buff; + } + SAFE_SPRINTF(buff, sizeof(buff), + "%s.%s = %s\n" + "%s = None\n" + "if _tmp_ff_:\n\tglobals()['%s'] = _tmp_ff_\n_tmp_ff_ = None\n", + m_mod_name.c_str(), m_all_pyclass[i].class_name.c_str(), m_all_pyclass[i].class_name.c_str(), + m_all_pyclass[i].class_name.c_str(), + m_all_pyclass[i].class_name.c_str() + ); + gen_class_str += buff; + //printf(gen_class_str.c_str()); + PyRun_SimpleString(gen_class_str.c_str()); + } + return 0; +} + + +bool ffpython_t::is_method_exist(const vector& src_, const string& new_) +{ + for (size_t i = 0; i < src_.size(); ++i) + { + if (new_ == src_[i].func_name) + { + return true; + } + } + return false; +} +bool ffpython_t::is_property_exist(const vector& src_, const string& new_) +{ + for (size_t i = 0; i < src_.size(); ++i) + { + if (new_ == src_[i].property_name) + { + return true; + } + } + return false; +} +pyclass_regigster_tool_t* ffpython_t::get_pyclass_info_by_name(const string& name_) +{ + for (size_t i = 0; i < m_all_pyclass.size(); ++i) + { + if (m_all_pyclass[i].class_name == name_) + { + return &(m_all_pyclass[i]); + } + } + return NULL; +} + diff --git a/python2.7/VersionForRead/ffpython.h b/oldversion/python2.7/VersionForRead/ffpython.h similarity index 97% rename from python2.7/VersionForRead/ffpython.h rename to oldversion/python2.7/VersionForRead/ffpython.h index 5585f5f..22faabe 100644 --- a/python2.7/VersionForRead/ffpython.h +++ b/oldversion/python2.7/VersionForRead/ffpython.h @@ -1,481 +1,481 @@ -#ifndef __FFPYTHON_H_ -#define __FFPYTHON_H_ - -#include -#include - -#include -using namespace std; - -#include "pyops_base.h" -#include "pyops_for_embed.h" -#include "pyops_for_extend.h" - -class ffpython_t -{ - struct reg_info_t - { - reg_info_t():args_num(0),option_args_num(0),func_addr(0){} - int args_num; - int option_args_num; - long func_addr; - PyCFunction func; - string func_name; - string func_impl_name; - string doc; - string doc_impl; - }; - -public: - ffpython_t(); - ~ffpython_t(); - - static int init_py(); - static int final_py(); - - static int add_path(const string& path_); - - static int run_string(const string& py_); - static int reload(const string& py_name_); - static int load(const string& py_name_); - - - //! 将需要注册的函数、类型注册到python虚拟机 - int init(const string& mod_name_, string doc_ = ""); - - //! 注册static function, - template - ffpython_t& reg(T func_, const string& func_name_, string doc_ = "") - { - reg_info_t tmp; - tmp.args_num = pyext_func_traits_t::args_num(); - tmp.option_args_num = pyext_func_traits_t::option_args_num(); - tmp.func = (PyCFunction)pyext_func_traits_t::pyfunc; - tmp.func_name= func_name_; - tmp.func_impl_name = func_name_ + "_internal_"; - tmp.doc = doc_; - tmp.doc_impl = string("internal use, please call ") + func_name_; - tmp.func_addr= (long)func_; - - m_func_info.push_back(tmp); - return *this; - } - - //! 注册c++ class - template - pyclass_regigster_tool_t& reg_class(const string& class_name_, string doc_ = "", string inherit_name_ = "") - { - if (pyclass_base_info_t::pytype_info.class_name.empty() == false) - throw runtime_error("this type has been registed"); - - pyclass_base_info_t::pytype_info.class_name = class_name_; - //pyclass_base_info_t::pytype_info.mod_name = m_mod_name; - pyclass_base_info_t::pytype_info.total_args_num = pyext_func_traits_t::args_num() + - pyext_func_traits_t::option_args_num(); - - pyclass_regigster_tool_t tmp; - tmp.class_name = class_name_; - tmp.class_real_name = class_name_ + "_internal_"; - tmp.inherit_name = inherit_name_; - tmp.doc = doc_; - tmp.dector = (destructor)pyclass_base_info_t::free_obj; - tmp.init = (initproc)pyclass_ctor_tool_t::init_obj; - tmp.ctor = pyclass_base_info_t::alloc_obj; - tmp.type_size = sizeof(typename pyclass_base_info_t::obj_data_t); - tmp.args_num = pyext_func_traits_t::args_num(); - tmp.option_args_num = pyext_func_traits_t::option_args_num(); - tmp.static_pytype_info = &(pyclass_base_info_t::pytype_info); - //! 注册析构函数,python若不调用析构函数,当对象被gc时自动调用 - tmp.delete_func = (PyCFunction)pyclass_base_info_t::release; - m_all_pyclass.push_back(tmp); - - return m_all_pyclass.back(); - } - - - //! 调用python函数,最多支持9个参数 - template - RET_V call(const string& mod_name_, const string& func_) - { - pycall_arg_t args(0); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1) - { - pycall_arg_t args(1); - args.add(a1); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2) - { - pycall_arg_t args(2); - args.add(a1).add(a2); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3) - { - pycall_arg_t args(3); - args.add(a1).add(a2).add(a3); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) - { - pycall_arg_t args(4); - args.add(a1).add(a2).add(a3).add(a4); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5) - { - pycall_arg_t args(5); - args.add(a1).add(a2).add(a3).add(a4).add(a5); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5,const ARG6& a6) - { - pycall_arg_t args(6); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5,const ARG6& a6,const ARG7& a7) - { - pycall_arg_t args(7); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) - { - pycall_arg_t args(8); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) - { - pycall_arg_t args(9); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8).add(a9); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - //!call python class method begin****************************************************************** - template - RET_V obj_call(PyObject* pobj, const string& func_) - { - pycall_arg_t args(0); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1) - { - pycall_arg_t args(1); - args.add(a1); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2) - { - pycall_arg_t args(2); - args.add(a1).add(a2); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3) - { - pycall_arg_t args(3); - args.add(a1).add(a2).add(a3); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) - { - pycall_arg_t args(4); - args.add(a1).add(a2).add(a3).add(a4); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5) - { - pycall_arg_t args(5); - args.add(a1).add(a2).add(a3).add(a4).add(a5); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5,const ARG6& a6) - { - pycall_arg_t args(6); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5,const ARG6& a6,const ARG7& a7) - { - pycall_arg_t args(7); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) - { - pycall_arg_t args(8); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) - { - pycall_arg_t args(9); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8).add(a9); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - //!call python class method end****************************************************************** - - //!call python lambad function begin ############################################################ - template - RET_V call_lambda(PyObject* pobj) - { - pycall_arg_t args(0); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1) - { - pycall_arg_t args(1); - args.add(a1); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2) - { - pycall_arg_t args(2); - args.add(a1).add(a2); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3) - { - pycall_arg_t args(3); - args.add(a1).add(a2).add(a3); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) - { - pycall_arg_t args(4); - args.add(a1).add(a2).add(a3).add(a4); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5) - { - pycall_arg_t args(5); - args.add(a1).add(a2).add(a3).add(a4).add(a5); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5,const ARG6& a6) - { - pycall_arg_t args(6); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5,const ARG6& a6,const ARG7& a7) - { - pycall_arg_t args(7); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) - { - pycall_arg_t args(8); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) - { - pycall_arg_t args(9); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8).add(a9); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - //!call python lambad function ennd ############################################################ - template - RET_V get_global_var(const string& mod_name_, const string& var_name_) - { - PyObject *pName = NULL, *pModule = NULL; - string err_msg; - - pName = PyString_FromString(mod_name_.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - } - - pytype_tool_impl_t pyret; - PyObject *pvalue = PyObject_GetAttrString(pModule, var_name_.c_str()); - Py_DECREF(pModule); - - if (!pvalue) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - } - - if (pyret.parse_value(pvalue)) - { - Py_XDECREF(pvalue); - throw runtime_error("type invalid"); - } - Py_XDECREF(pvalue); - return pyret.get_value(); - } - - template - int set_global_var(const string& mod_name_, const string& var_name_, const T& val_) - { - PyObject *pName = NULL, *pModule = NULL; - string err_msg; - - pName = PyString_FromString(mod_name_.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - } - - PyObject* pval = pytype_traits_t::pyobj_from_cppobj(val_); - int ret = PyObject_SetAttrString(pModule, var_name_.c_str(), pval); - Py_DECREF(pModule); - - return ret != -1? 0: -1; - } - - template - RET_V getattr(PyObject* pModule, const string& var_name_) - { - string err_msg; - if (NULL == pModule) - { - throw runtime_error("getattr object ptr null"); - } - - pytype_tool_impl_t pyret; - PyObject *pvalue = PyObject_GetAttrString(pModule, var_name_.c_str()); - - if (!pvalue) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - } - - if (pyret.parse_value(pvalue)) - { - Py_XDECREF(pvalue); - throw runtime_error("type invalid"); - } - Py_XDECREF(pvalue); - return pyret.get_value(); - } - - - void cache_pyobject(PyObject* pobj) - { - m_cache_pyobject.push_back(pobj); - } - void clear_cache_pyobject() - { - if (Py_IsInitialized()) - { - for (size_t i = 0; i < m_cache_pyobject.size(); ++i) - { - Py_XDECREF(m_cache_pyobject[i]); - } - m_cache_pyobject.clear(); - } - } -private: - PyObject* init_method(); - int init_pyclass(PyObject* m); - - - bool is_method_exist(const vector& src_, const string& new_); - bool is_property_exist(const vector& src_, const string& new_); - pyclass_regigster_tool_t* get_pyclass_info_by_name(const string& name_); - -private: - string m_mod_name; - string m_mod_doc; - vector m_pymethod_defs; - vector m_func_info; - - //! reg class - vector m_all_pyclass; - //! cache some pyobject for optimize - vector m_cache_pyobject; -}; - - -#endif +#ifndef __FFPYTHON_H_ +#define __FFPYTHON_H_ + +#include +#include + +#include +using namespace std; + +#include "pyops_base.h" +#include "pyops_for_embed.h" +#include "pyops_for_extend.h" + +class ffpython_t +{ + struct reg_info_t + { + reg_info_t():args_num(0),option_args_num(0),func_addr(0){} + int args_num; + int option_args_num; + long func_addr; + PyCFunction func; + string func_name; + string func_impl_name; + string doc; + string doc_impl; + }; + +public: + ffpython_t(); + ~ffpython_t(); + + static int init_py(); + static int final_py(); + + static int add_path(const string& path_); + + static int run_string(const string& py_); + static int reload(const string& py_name_); + static int load(const string& py_name_); + + + //! 将需要注册的函数、类型注册到python虚拟机 + int init(const string& mod_name_, string doc_ = ""); + + //! 注册static function, + template + ffpython_t& reg(T func_, const string& func_name_, string doc_ = "") + { + reg_info_t tmp; + tmp.args_num = pyext_func_traits_t::args_num(); + tmp.option_args_num = pyext_func_traits_t::option_args_num(); + tmp.func = (PyCFunction)pyext_func_traits_t::pyfunc; + tmp.func_name= func_name_; + tmp.func_impl_name = func_name_ + "_internal_"; + tmp.doc = doc_; + tmp.doc_impl = string("internal use, please call ") + func_name_; + tmp.func_addr= (long)func_; + + m_func_info.push_back(tmp); + return *this; + } + + //! 注册c++ class + template + pyclass_regigster_tool_t& reg_class(const string& class_name_, string doc_ = "", string inherit_name_ = "") + { + if (pyclass_base_info_t::pytype_info.class_name.empty() == false) + throw runtime_error("this type has been registed"); + + pyclass_base_info_t::pytype_info.class_name = class_name_; + //pyclass_base_info_t::pytype_info.mod_name = m_mod_name; + pyclass_base_info_t::pytype_info.total_args_num = pyext_func_traits_t::args_num() + + pyext_func_traits_t::option_args_num(); + + pyclass_regigster_tool_t tmp; + tmp.class_name = class_name_; + tmp.class_real_name = class_name_ + "_internal_"; + tmp.inherit_name = inherit_name_; + tmp.doc = doc_; + tmp.dector = (destructor)pyclass_base_info_t::free_obj; + tmp.init = (initproc)pyclass_ctor_tool_t::init_obj; + tmp.ctor = pyclass_base_info_t::alloc_obj; + tmp.type_size = sizeof(typename pyclass_base_info_t::obj_data_t); + tmp.args_num = pyext_func_traits_t::args_num(); + tmp.option_args_num = pyext_func_traits_t::option_args_num(); + tmp.static_pytype_info = &(pyclass_base_info_t::pytype_info); + //! 注册析构函数,python若不调用析构函数,当对象被gc时自动调用 + tmp.delete_func = (PyCFunction)pyclass_base_info_t::release; + m_all_pyclass.push_back(tmp); + + return m_all_pyclass.back(); + } + + + //! 调用python函数,最多支持9个参数 + template + RET_V call(const string& mod_name_, const string& func_) + { + pycall_arg_t args(0); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1) + { + pycall_arg_t args(1); + args.add(a1); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2) + { + pycall_arg_t args(2); + args.add(a1).add(a2); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3) + { + pycall_arg_t args(3); + args.add(a1).add(a2).add(a3); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) + { + pycall_arg_t args(4); + args.add(a1).add(a2).add(a3).add(a4); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5) + { + pycall_arg_t args(5); + args.add(a1).add(a2).add(a3).add(a4).add(a5); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5,const ARG6& a6) + { + pycall_arg_t args(6); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5,const ARG6& a6,const ARG7& a7) + { + pycall_arg_t args(7); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) + { + pycall_arg_t args(8); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + template + RET_V call(const string& mod_name_, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) + { + pycall_arg_t args(9); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8).add(a9); + pytype_tool_impl_t pyret; + return pycall_t::call(mod_name_, func_, args, pyret); + } + //!call python class method begin****************************************************************** + template + RET_V obj_call(PyObject* pobj, const string& func_) + { + pycall_arg_t args(0); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1) + { + pycall_arg_t args(1); + args.add(a1); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2) + { + pycall_arg_t args(2); + args.add(a1).add(a2); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3) + { + pycall_arg_t args(3); + args.add(a1).add(a2).add(a3); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) + { + pycall_arg_t args(4); + args.add(a1).add(a2).add(a3).add(a4); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5) + { + pycall_arg_t args(5); + args.add(a1).add(a2).add(a3).add(a4).add(a5); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5,const ARG6& a6) + { + pycall_arg_t args(6); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5,const ARG6& a6,const ARG7& a7) + { + pycall_arg_t args(7); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) + { + pycall_arg_t args(8); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + template + RET_V obj_call(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) + { + pycall_arg_t args(9); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8).add(a9); + pytype_tool_impl_t pyret; + return pycall_t::call_obj_method(pobj, func_, args, pyret); + } + //!call python class method end****************************************************************** + + //!call python lambad function begin ############################################################ + template + RET_V call_lambda(PyObject* pobj) + { + pycall_arg_t args(0); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1) + { + pycall_arg_t args(1); + args.add(a1); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2) + { + pycall_arg_t args(2); + args.add(a1).add(a2); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3) + { + pycall_arg_t args(3); + args.add(a1).add(a2).add(a3); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) + { + pycall_arg_t args(4); + args.add(a1).add(a2).add(a3).add(a4); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5) + { + pycall_arg_t args(5); + args.add(a1).add(a2).add(a3).add(a4).add(a5); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5,const ARG6& a6) + { + pycall_arg_t args(6); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5,const ARG6& a6,const ARG7& a7) + { + pycall_arg_t args(7); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) + { + pycall_arg_t args(8); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + template + RET_V call_lambda(PyObject* pobj, const string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, + const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) + { + pycall_arg_t args(9); + args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8).add(a9); + pytype_tool_impl_t pyret; + return pycall_t::call_lambda(pobj, args, pyret); + } + //!call python lambad function ennd ############################################################ + template + RET_V get_global_var(const string& mod_name_, const string& var_name_) + { + PyObject *pName = NULL, *pModule = NULL; + string err_msg; + + pName = PyString_FromString(mod_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + } + + pytype_tool_impl_t pyret; + PyObject *pvalue = PyObject_GetAttrString(pModule, var_name_.c_str()); + Py_DECREF(pModule); + + if (!pvalue) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + } + + if (pyret.parse_value(pvalue)) + { + Py_XDECREF(pvalue); + throw runtime_error("type invalid"); + } + Py_XDECREF(pvalue); + return pyret.get_value(); + } + + template + int set_global_var(const string& mod_name_, const string& var_name_, const T& val_) + { + PyObject *pName = NULL, *pModule = NULL; + string err_msg; + + pName = PyString_FromString(mod_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + } + + PyObject* pval = pytype_traits_t::pyobj_from_cppobj(val_); + int ret = PyObject_SetAttrString(pModule, var_name_.c_str(), pval); + Py_DECREF(pModule); + + return ret != -1? 0: -1; + } + + template + RET_V getattr(PyObject* pModule, const string& var_name_) + { + string err_msg; + if (NULL == pModule) + { + throw runtime_error("getattr object ptr null"); + } + + pytype_tool_impl_t pyret; + PyObject *pvalue = PyObject_GetAttrString(pModule, var_name_.c_str()); + + if (!pvalue) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + } + + if (pyret.parse_value(pvalue)) + { + Py_XDECREF(pvalue); + throw runtime_error("type invalid"); + } + Py_XDECREF(pvalue); + return pyret.get_value(); + } + + + void cache_pyobject(PyObject* pobj) + { + m_cache_pyobject.push_back(pobj); + } + void clear_cache_pyobject() + { + if (Py_IsInitialized()) + { + for (size_t i = 0; i < m_cache_pyobject.size(); ++i) + { + Py_XDECREF(m_cache_pyobject[i]); + } + m_cache_pyobject.clear(); + } + } +private: + PyObject* init_method(); + int init_pyclass(PyObject* m); + + + bool is_method_exist(const vector& src_, const string& new_); + bool is_property_exist(const vector& src_, const string& new_); + pyclass_regigster_tool_t* get_pyclass_info_by_name(const string& name_); + +private: + string m_mod_name; + string m_mod_doc; + vector m_pymethod_defs; + vector m_func_info; + + //! reg class + vector m_all_pyclass; + //! cache some pyobject for optimize + vector m_cache_pyobject; +}; + + +#endif diff --git a/python2.7/VersionForRead/pyops_base.h b/oldversion/python2.7/VersionForRead/pyops_base.h similarity index 96% rename from python2.7/VersionForRead/pyops_base.h rename to oldversion/python2.7/VersionForRead/pyops_base.h index ccb0f5c..9fdb066 100644 --- a/python2.7/VersionForRead/pyops_base.h +++ b/oldversion/python2.7/VersionForRead/pyops_base.h @@ -1,1123 +1,1123 @@ -#ifndef __PYOPS_BASE_ -#define __PYOPS_BASE_ - - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -#ifdef _WIN32 -#define SAFE_SPRINTF _snprintf_s -#else -#define SAFE_SPRINTF snprintf -#endif - - - -//! 获取python异常信息 -struct pyops_t -{ - static int traceback(string& ret_); -}; -struct cpp_void_t{}; - -//! 用于抽取类型、类型对应的引用 -template -struct type_ref_traits_t; - -//! 用于python 可选参数 -template -struct pyoption_t -{ - typedef typename type_ref_traits_t::value_t value_t; - pyoption_t():m_set_flag(false){} - bool is_set() const { return m_set_flag;} - void set() { m_set_flag = true;} - value_t& value() { return m_value;} - const value_t& value() const{ return m_value;} - - const value_t& value(const value_t& default_) - { - if (is_set()) - return m_value; - else - return default_; - } - bool m_set_flag; - value_t m_value; -}; -//! 用于判断是否是可选参数 -template -struct pyoption_traits_t; - -//! pytype_traits_t 封装 PyLong_FromLong 相关的操作,用于为调用python生成参数 -template -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const char* const val_) - { - return PyString_FromString(val_); - } - /* - static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) - { - if (true == PyString_Check(pvalue_)) - { - m_ret = PyString_AsString(pvalue_); - return 0; - } - return -1; - } - */ - static const char* get_typename() { return "string";} -}; - -//! 用于调用python函数,生成tuple类型的python函数参数的工具类 -struct pycall_arg_t -{ - pycall_arg_t(int arg_num): - arg_index(0), - pargs_tuple(PyTuple_New(arg_num)) - {} - ~pycall_arg_t() - { - release(); - } - PyObject * get_args() const - { - return pargs_tuple; - } - template - pycall_arg_t& add(const T& val_) - { - if (arg_index < PyTuple_Size(pargs_tuple)) - { - PyObject* tmp_arg = pytype_traits_t::pyobj_from_cppobj(val_); - PyTuple_SetItem(pargs_tuple, arg_index, tmp_arg); - ++arg_index; - } - return *this; - } - void release() - { - if (pargs_tuple) - { - Py_DECREF(pargs_tuple); - pargs_tuple = NULL; - } - } - int arg_index; - PyObject * pargs_tuple; -}; - -//! 用于调用python函数,获取返回值的工具类 -class pytype_tool_t -{ -public: - virtual ~pytype_tool_t(){}; - virtual int parse_value(PyObject *pvalue_) = 0; - virtual const char* return_type() {return "";} - virtual bool need_release() { return false; } -}; - -//! 用于调用python函数,获取返回值的工具泛型类 -template -class pytype_tool_impl_t; -//! 封装调用python函数的C API -struct pycall_t -{ - static int call_func(PyObject *pModule, const string& mod_name_, const string& func_name_, - pycall_arg_t& pyarg_, pytype_tool_t& pyret_, string& err_) - { - PyObject *pFunc = PyObject_GetAttrString(pModule, func_name_.c_str()); - if (pFunc && PyCallable_Check(pFunc)) { - PyObject *pArgs = pyarg_.get_args(); - PyObject *pValue = PyObject_CallObject(pFunc, pArgs); - pyarg_.release();//! 等价于Py_DECREF(pArgs); - - if (pValue != NULL) { - if (pyret_.parse_value(pValue)) - { - err_ += "value returned is not "; - err_ += pyret_.return_type(); - err_ += string(" ") + func_name_ + " in " + mod_name_; - } - if (pyret_.need_release()){ - Py_DECREF(pValue); - } - } - } - else - { - err_ += "Cannot find function "; - err_ += func_name_ + " in " + mod_name_ + ","; - } - - Py_XDECREF(pFunc); - if (PyErr_Occurred()) - { - pyops_t::traceback(err_); - return 0; - } - return 0; - } - static int call_func_obj(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_t& pyret_, string& err_) - { - if (pFunc && PyCallable_Check(pFunc)) { - PyObject *pArgs = pyarg_.get_args(); - PyObject *pValue = PyObject_CallObject(pFunc, pArgs); - pyarg_.release();//! 等价于Py_DECREF(pArgs); - - if (pValue != NULL) { - if (pyret_.parse_value(pValue)) - { - err_ += "value returned is not "; - err_ += pyret_.return_type(); - } - if (pyret_.need_release()){ - Py_DECREF(pValue); - } - } - } - else - { - err_ += "invalid function"; - } - - if (PyErr_Occurred()) - { - pyops_t::traceback(err_); - return 0; - } - return 0; - } - template - static const T& call(const string& mod_name_, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); - template - static const T& call_obj_method(PyObject *pObj, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); - template - static const T& call_lambda(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); -}; -//! 用于扩展python的工具类,用来解析参数 -struct pyext_tool_t; - - -template -struct pyext_return_tool_t; - -//! 用于扩展python,生成pyobject类型的返回值给python -template -struct pyext_func_traits_t; - -//! 用于扩展python,traits出注册给python的函数接口 -#ifndef PYCTOR -#define PYCTOR int (*) -#endif -//! 表示void类型,由于void类型不能return,用void_ignore_t适配 -template -struct void_ignore_t; - -template -struct void_ignore_t -{ - typedef T value_t; -}; - -template<> -struct void_ignore_t -{ - typedef cpp_void_t value_t; -}; - -#define RET_V typename void_ignore_t::value_t - -//! 记录各个基类和子类的相互关系 -struct cpp_to_pyclass_reg_info_t -{ - struct inherit_info_t - { - inherit_info_t():pytype_def(NULL){} - PyTypeObject* pytype_def; - string inherit_name; - set all_child; - }; - typedef map inherit_info_map_t; - static inherit_info_map_t& get_all_info() - { - static inherit_info_map_t inherit_info; - return inherit_info; - } - - static void add(const string& child_, const string& base_, PyTypeObject* def_) - { - inherit_info_t tmp; - tmp.inherit_name = base_; - tmp.pytype_def = def_; - get_all_info()[child_] = tmp; - get_all_info()[base_].all_child.insert(def_); - } - static bool is_instance(PyObject* pysrc, const string& class_) - { - inherit_info_map_t& inherit_info = get_all_info(); - inherit_info_t& tmp = inherit_info[class_]; - if (tmp.pytype_def && PyObject_TypeCheck(pysrc, tmp.pytype_def)) - { - return true; - } - for (set::iterator it = tmp.all_child.begin(); it != tmp.all_child.end(); ++it) - { - if (*it && PyObject_TypeCheck(pysrc, *it)) - { - return true; - } - } - - return false; - } - -}; - - -//! 记录C++ class 对应到python中的名称、参数信息等,全局 -struct static_pytype_info_t -{ - string class_name; - string mod_name; - int total_args_num; - PyTypeObject* pytype_def; -}; - -//! 工具类,用于生成分配python class的接口,包括分配、释放 -template -struct pyclass_base_info_t -{ - struct obj_data_t - { - obj_data_t():obj(NULL){} - - PyObject_HEAD; - T* obj; - bool forbid_release; - void disable_auto_release(){ forbid_release = true; } - void release() - { - if (obj) - { - delete obj; - obj = NULL; - } - } - }; - - static void free_obj(obj_data_t* self) - { - if (false == self->forbid_release && self->obj) - { - self->release(); - } - self->ob_type->tp_free((PyObject*)self); - } - - static PyObject *alloc_obj(PyTypeObject *type, PyObject *args, PyObject *kwds) - { - obj_data_t *self = (obj_data_t *)type->tp_alloc(type, 0); - return (PyObject *)self; - } - static PyObject *release(PyTypeObject *type, PyObject *args) - { - obj_data_t *self = (obj_data_t *)type; - self->release(); - return Py_BuildValue("i", 1); - } - static static_pytype_info_t pytype_info; -}; -template -static_pytype_info_t pyclass_base_info_t::pytype_info; - -//! 方便生成pyclass 初始化函数 -template -struct pyclass_ctor_tool_t; - -//! used to gen method of py class -template -struct pyclass_method_gen_t; - -//! 防止出现指针为NULL调用出错 -#define NULL_PTR_GUARD(X) if (NULL == X) {PyErr_SetString(PyExc_TypeError, "obj data ptr NULL");return NULL;} - -//! 用于生成python 的getter和setter接口,适配于c++ class的成员变量 -template -struct pyclass_member_func_gen_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - typedef RET CLASS_TYPE::* property_ptr_t; - - static PyObject *getter_func(obj_data_t *self, void *closure) - { - property_ptr_t property_ptr; - ::memcpy((void*)&property_ptr, (const void*)&closure, sizeof(closure)); - NULL_PTR_GUARD(self->obj); - CLASS_TYPE* p = self->obj; - return pytype_traits_t::pyobj_from_cppobj(p->*property_ptr); - } - static int setter_func(obj_data_t *self, PyObject *value, void *closure) - { - property_ptr_t property_ptr; - ::memcpy((void*)&property_ptr, (const void*)&closure, sizeof(closure)); - CLASS_TYPE* p = self->obj; - - return pytype_traits_t::pyobj_to_cppobj(value, p->*property_ptr); - } -}; - -//! 用于C++ 注册class的工具类,会记录class对应的名称、成员方法、成员变量 -class pyclass_regigster_tool_t -{ -public: - struct method_info_t - { - PyCFunction func; - string func_name; - string func_real_name; - string doc; - string doc_real; - int args_num; - int option_args_num; - long func_addr; - }; - struct property_info_t - { - void* ptr; - string property_name; - string doc; - getter getter_func; - setter setter_func; - }; - virtual ~pyclass_regigster_tool_t(){} - - typedef PyObject *(*pyobj_alloc_t)(PyTypeObject*, PyObject*, PyObject*); - - string class_name; - string class_real_name; - string class_name_with_mod; - string class_reel_name_with_mod; - string inherit_name; - int type_size; - string doc; - int args_num; - int option_args_num; - destructor dector; - initproc init; - pyobj_alloc_t ctor; - - //! member functions - PyCFunction delete_func; - vector methods_info; - //! property - vector propertys_info; - //! for init module - PyTypeObject pytype_def; - //! method - vector pymethod_def; - //! property - vector pyproperty_def; - - //! 静态类型需要全局记录该类型被注册成神马python 类型 - static_pytype_info_t* static_pytype_info; - - template - pyclass_regigster_tool_t& reg(FUNC f_, const string& func_name_, string doc_ = "") - { - method_info_t tmp; - tmp.func_name = func_name_; - tmp.func_real_name = func_name_ + "_internal_"; - tmp.doc = doc_; - tmp.doc_real = "internal use"; - tmp.func = (PyCFunction)pyclass_method_gen_t::pymethod; - tmp.args_num = pyclass_method_gen_t::args_num(); - tmp.option_args_num = pyclass_method_gen_t::option_args_num(); - ::memcpy((void*)&tmp.func_addr, (const void*)&f_, sizeof(void*)); - methods_info.push_back(tmp); - return *this; - } - template - pyclass_regigster_tool_t& reg_property(RET CLASS_TYPE::* member_, const string& member_name_, string doc_ = "") - { - property_info_t tmp; - ::memcpy((void*)&tmp.ptr, (const void*)&member_, sizeof(member_)); - tmp.property_name = member_name_; - tmp.doc = doc_; - tmp.getter_func = (getter)pyclass_member_func_gen_t::getter_func; - tmp.setter_func = (setter)pyclass_member_func_gen_t::setter_func; - propertys_info.push_back(tmp); - return *this; - } -}; - - -template -struct type_ref_traits_t -{ - typedef T value_t; - typedef T& ref_t; - value_t value; -}; -template -struct type_ref_traits_t -{ - typedef T value_t; - typedef T& ref_t; - value_t value; -}; -template -struct type_ref_traits_t -{ - typedef T value_t; - typedef T& ref_t; - value_t value; -}; -//! 用于判断是否是可选参数 -template -struct pyoption_traits_t -{ - static int is() { return 0;} -}; -template -struct pyoption_traits_t > -{ - static int is() { return 1;} -}; - - -template<>//typename T> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const long& val_) - { - return PyLong_FromLong(long(val_)); - } - static int pyobj_to_cppobj(PyObject *pvalue_, long& m_ret) - { - if (true == PyLong_Check(pvalue_)) - { - m_ret = (long)PyLong_AsLong(pvalue_); - return 0; - } - else if (true == PyInt_Check(pvalue_)) - { - m_ret = (long)PyInt_AsLong(pvalue_); - return 0; - } - return -1; - } - static const char* get_typename() { return "long";} -}; - -#define IMPL_INT_CODE(X) \ -template<> \ -struct pytype_traits_t \ -{ \ - static PyObject* pyobj_from_cppobj(const X& val_) \ - { \ - return PyInt_FromLong(long(val_)); \ - } \ - static int pyobj_to_cppobj(PyObject *pvalue_, X& m_ret) \ - { \ - if (true == PyLong_Check(pvalue_)) \ - { \ - m_ret = (X)PyLong_AsLong(pvalue_); \ - return 0; \ - } \ - else if (true == PyInt_Check(pvalue_)) \ - { \ - m_ret = (X)PyInt_AsLong(pvalue_); \ - return 0; \ - } \ - return -1; \ - } \ - static const char* get_typename() { return #X;} \ -}; - -IMPL_INT_CODE(int) -IMPL_INT_CODE(unsigned int) -IMPL_INT_CODE(short) -IMPL_INT_CODE(unsigned short) -IMPL_INT_CODE(char) -IMPL_INT_CODE(unsigned char) - -#ifdef _WIN32 -IMPL_INT_CODE(unsigned long) -#else -#ifndef __x86_64__ -IMPL_INT_CODE(int64_t) -#endif -IMPL_INT_CODE(uint64_t) -#endif - -template -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const T* val_) - { - const string& mod_name = pyclass_base_info_t::pytype_info.mod_name; - const string& class_name = pyclass_base_info_t::pytype_info.class_name; - PyObject *pName = NULL, *pModule = NULL, *pValue = NULL; - - if (class_name.empty()) - return pytype_traits_t::pyobj_from_cppobj(long(val_)); - - pName = PyString_FromString(mod_name.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - if (PyErr_Occurred()) - PyErr_Print(); - fprintf(stderr, "Failed to load \"%s\"\n", mod_name.c_str()); - assert(NULL && "this can not be happened"); - return NULL; - } - PyObject *pyclass = PyObject_GetAttrString(pModule, class_name.c_str()); - if (pyclass && PyCallable_Check(pyclass)) { - PyObject *pArgs = PyTuple_New(pyclass_base_info_t::pytype_info.total_args_num+1); - for (int i = 0; i< pyclass_base_info_t::pytype_info.total_args_num; ++i) - { - PyTuple_SetItem(pArgs, i, pytype_traits_t::pyobj_from_cppobj(0)); - } - - PyObject *palloc = pyclass_base_info_t::alloc_obj(pyclass_base_info_t::pytype_info.pytype_def, NULL, NULL); - typename pyclass_base_info_t::obj_data_t* pdest_obj = (typename pyclass_base_info_t::obj_data_t*)palloc; - //pdest_obj->obj = val_; - ::memcpy((void*)&pdest_obj->obj, (const void*)&val_, sizeof(pdest_obj->obj)); - pdest_obj->disable_auto_release(); - PyTuple_SetItem(pArgs, pyclass_base_info_t::pytype_info.total_args_num, palloc); - pValue = PyObject_CallObject(pyclass, pArgs); - Py_XDECREF(pArgs); - } - - Py_XDECREF(pyclass); - Py_DECREF(pModule); - return pValue; - } - - static int pyobj_to_cppobj(PyObject *pvalue_, T*& m_ret) - { - PyObject *pysrc = PyObject_GetAttrString(pvalue_, "obj"); - //!PyObject_TypeCheck(pysrc, pyclass_base_info_t::pytype_info.pytype_def)) { - if (NULL == pysrc || false == cpp_to_pyclass_reg_info_t::is_instance(pysrc, pyclass_base_info_t::pytype_info.class_name)) - { - Py_XDECREF(pysrc); - return -1; - } - typename pyclass_base_info_t::obj_data_t* pdest_obj = (typename pyclass_base_info_t::obj_data_t*)pysrc; - - m_ret = pdest_obj->obj; - Py_XDECREF(pysrc); - return 0; - } - - static const char* get_typename() { return pyclass_base_info_t::pytype_info.class_name.c_str();} -}; - -template -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(T* val_) - { - return pytype_traits_t::pyobj_from_cppobj(val_); - } - static int pyobj_to_cppobj(PyObject *pvalue_,T*& m_ret) - { - return pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret); - } - static const char* get_typename() { return pyclass_base_info_t::pytype_info.class_name.c_str();} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(PyObject* val_) - { - return val_; - } - static int pyobj_to_cppobj(PyObject *pvalue_, PyObject*& m_ret) - { - m_ret = pvalue_; - return 0; - } - static const char* get_typename() { return "PyObject";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const char* const val_) - { - return PyString_FromString(val_); - } - /* - static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) - { - if (true == PyString_Check(pvalue_)) - { - m_ret = PyString_AsString(pvalue_); - return 0; - } - return -1; - } - */ - static const char* get_typename() { return "string";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const char*& val_) - { - return PyString_FromString(val_); - } - /* - static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) - { - if (true == PyString_Check(pvalue_)) - { - m_ret = PyString_AsString(pvalue_); - return 0; - } - return -1; - } - */ - static const char* get_typename() { return "string";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(bool val_) - { - if (val_) - { - Py_RETURN_TRUE; - } - Py_RETURN_FALSE; - } - static int pyobj_to_cppobj(PyObject *pvalue_, bool& m_ret) - { - if (Py_False == pvalue_|| Py_None == pvalue_) - { - m_ret = false; - } - else - { - m_ret = true; - } - return 0; - } - static const char* get_typename() { return "bool";} -}; - -template -struct pytype_traits_t > -{ - static int pyobj_to_cppobj(PyObject *pvalue_, pyoption_t& m_ret) - { - if (Py_None == pvalue_) - { - return 0; - } - else if (0 == pytype_traits_t::value_t>::pyobj_to_cppobj(pvalue_, m_ret.value())) - { - m_ret.set(); - return 0; - } - return -1; - } - static const char* get_typename() { return "pyoption_t";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const string& val_) - { - return PyString_FromStringAndSize(val_.c_str(), val_.size()); - } - static int pyobj_to_cppobj(PyObject *pvalue_, string& m_ret) - { - if (true == PyString_Check(pvalue_)) - { - char* pDest = NULL; - Py_ssize_t nLen = 0; - PyString_AsStringAndSize(pvalue_, &pDest, &nLen); - - m_ret.assign(pDest, nLen); - return 0; - } - else if (true == PyUnicode_Check(pvalue_)) - { - char* pDest = NULL; - Py_ssize_t nLen = 0; - PyString_AsStringAndSize(pvalue_, &pDest, &nLen); - m_ret.assign(pDest, nLen); - return 0; - /* -#ifdef _WIN32 - PyObject* retStr = PyUnicode_AsEncodedString(pvalue_, "gbk", ""); -#else - PyObject* retStr = PyUnicode_AsUTF8String(pvalue_); -#endif - if (retStr) - { - m_ret = PyString_AsString(retStr); - Py_XDECREF(retStr); - return 0; - } - */ - } - return -1; - } - static const char* get_typename() { return "string";} -}; - -#ifdef _WIN32 -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const wstring& wstr) - { - return PyUnicode_FromWideChar(wstr.c_str(), wstr.length()); - } - static int pyobj_to_cppobj(PyObject *pvalue_, wstring& wstr_ret) - { - if (true == PyString_Check(pvalue_)) - { - PyObject* retStr = PyUnicode_FromObject(pvalue_); - if (retStr) - { - int n = PyUnicode_GetSize(retStr); - wstr_ret.resize(n); - n = PyUnicode_AsWideChar((PyUnicodeObject*)retStr, &(wstr_ret[0]), n); - Py_XDECREF(retStr); - return 0; - } - return 0; - } - else if (true == PyUnicode_Check(pvalue_)) - { - int n = PyUnicode_GetSize(pvalue_); - wstr_ret.resize(n); - n = PyUnicode_AsWideChar((PyUnicodeObject*)pvalue_, &(wstr_ret[0]), n); - return 0; - } - return -1; - } - static const char* get_typename() { return "wstring";} -}; -#endif - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(float val_) - { - return PyFloat_FromDouble(double(val_)); - } - static int pyobj_to_cppobj(PyObject *pvalue_, float& m_ret) - { - if (true == PyFloat_Check(pvalue_)) - { - m_ret = (float)PyFloat_AsDouble(pvalue_); - return 0; - } - return -1; - } - static const char* get_typename() { return "float";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(double val_) - { - return PyFloat_FromDouble(val_); - } - static int pyobj_to_cppobj(PyObject *pvalue_, double& m_ret) - { - if (true == PyFloat_Check(pvalue_)) - { - m_ret = PyFloat_AsDouble(pvalue_); - return 0; - } - return -1; - } - static const char* get_typename() { return "double";} -}; - -template -struct pytype_traits_t > -{ - static PyObject* pyobj_from_cppobj(const vector& val_) - { - PyObject* ret = PyList_New(val_.size()); - for (size_t i = 0; i < val_.size(); ++i) - { - PyList_SetItem(ret, i, pytype_traits_t::pyobj_from_cppobj(val_[i])); - } - return ret; - } - static int pyobj_to_cppobj(PyObject *pvalue_, vector& m_ret) - { - m_ret.clear(); - if (true == PyTuple_Check(pvalue_)) - { - int n = PyTuple_Size(pvalue_); - for (int i = 0; i < n; ++i) - { - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyTuple_GetItem(pvalue_, i))) - { - return -1; - } - m_ret.push_back(ret_tool.get_value()); - } - return 0; - } - else if (true == PyList_Check(pvalue_)) - { - int n = PyList_Size(pvalue_); - for (int i = 0; i < n; ++i) - { - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyList_GetItem(pvalue_, i))) - { - return -1; - } - m_ret.push_back(ret_tool.get_value()); - } - return 0; - } - return -1; - } - static const char* get_typename() { return "vector";} -}; -template -struct pytype_traits_t > -{ - static PyObject* pyobj_from_cppobj(const list& val_) - { - size_t n = val_.size(); - PyObject* ret = PyList_New(n); - int i = 0; - for (typename list::const_iterator it = val_.begin(); it != val_.end(); ++it) - { - PyList_SetItem(ret, i++, pytype_traits_t::pyobj_from_cppobj(*it)); - } - return ret; - } - static int pyobj_to_cppobj(PyObject *pvalue_, list& m_ret) - { - pytype_tool_impl_t ret_tool; - if (true == PyTuple_Check(pvalue_)) - { - int n = PyTuple_Size(pvalue_); - for (int i = 0; i < n; ++i) - { - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyTuple_GetItem(pvalue_, i))) - { - return -1; - } - m_ret.push_back(ret_tool.get_value()); - } - return 0; - } - else if (true == PyList_Check(pvalue_)) - { - int n = PyList_Size(pvalue_); - for (int i = 0; i < n; ++i) - { - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyList_GetItem(pvalue_, i))) - { - return -1; - } - m_ret.push_back(ret_tool.get_value()); - } - return 0; - } - return -1; - } - static const char* get_typename() { return "list";} -}; -template -struct pytype_traits_t > -{ - static PyObject* pyobj_from_cppobj(const set& val_) - { - PyObject* ret = PySet_New(NULL); - for (typename set::const_iterator it = val_.begin(); it != val_.end(); ++it) - { - PyObject *v = pytype_traits_t::pyobj_from_cppobj(*it); - PySet_Add(ret, v); - Py_DECREF(v); - } - return ret; - } - static int pyobj_to_cppobj(PyObject *pvalue_, set& m_ret) - { - m_ret.clear(); - pytype_tool_impl_t ret_tool; - PyObject *iter = PyObject_GetIter(pvalue_); - PyObject *item = NULL; - while (NULL != iter && NULL != (item = PyIter_Next(iter))) - { - T tmp(); - if (pytype_traits_t::pyobj_to_cppobj(item, tmp)) - { - Py_DECREF(item); - Py_DECREF(iter); - return -1; - } - m_ret.insert(tmp); - Py_DECREF(item); - } - if (iter) - { - Py_DECREF(iter); - return 0; - } - return -1; - } - static const char* get_typename() { return "set";} -}; -template -struct pytype_traits_t > -{ - static PyObject* pyobj_from_cppobj(const map& val_) - { - PyObject* ret = PyDict_New(); - for (typename map::const_iterator it = val_.begin(); it != val_.end(); ++it) - { - PyObject *k = pytype_traits_t::pyobj_from_cppobj(it->first); - PyObject *v = pytype_traits_t::pyobj_from_cppobj(it->second); - PyDict_SetItem(ret, k, v); - Py_DECREF(k); - Py_DECREF(v); - } - return ret; - } - static int pyobj_to_cppobj(PyObject *pvalue_, map& m_ret) - { - m_ret.clear(); - pytype_tool_impl_t ret_tool_T; - pytype_tool_impl_t ret_tool_R; - if (true == PyDict_Check(pvalue_)) - { - PyObject *key = NULL, *value = NULL; - Py_ssize_t pos = 0; - - while (PyDict_Next(pvalue_, &pos, &key, &value)) - { - T tmp_key; - R tmp_value; - if (pytype_traits_t::pyobj_to_cppobj(key, tmp_key) || - pytype_traits_t::pyobj_to_cppobj(value, tmp_value)) - { - return -1; - } - m_ret[tmp_key] = tmp_value; - } - return 0; - } - return -1; - } - static const char* get_typename() { return "map";} -}; - -//! ��ȡpython�����ķ���ֵ,������ -template -class pytype_tool_impl_t: public pytype_tool_t -{ -public: - pytype_tool_impl_t():m_ret(){} - - virtual int parse_value(PyObject *pvalue_) - { - if (pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret)) - { - return -1; - } - return 0; - } - - const T& get_value() const { return m_ret; } - virtual const char* return_type() {return pytype_traits_t::get_typename();} -private: - T m_ret; -}; - -template<> -class pytype_tool_impl_t: public pytype_tool_t -{ -public: - pytype_tool_impl_t():m_ret(){} - - virtual int parse_value(PyObject *pvalue_) - { - return 0; - } - - const cpp_void_t& get_value() const { return m_ret; } - virtual const char* return_type() { return "void";} -private: - cpp_void_t m_ret; -}; -template -class pytype_tool_impl_t: public pytype_tool_t -{ -public: - pytype_tool_impl_t():m_ret(){} - - virtual int parse_value(PyObject *pvalue_) - { - if (pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret)) - { - return -1; - } - return 0; - } - - T* get_value() const { return m_ret; } -private: - T* m_ret; -}; - - -template<> -class pytype_tool_impl_t: public pytype_tool_t -{ -public: - pytype_tool_impl_t():m_ret(){} - - virtual int parse_value(PyObject *pvalue_) - { - m_ret = pvalue_; - return 0; - } - - PyObject*& get_value() { return m_ret; } - bool need_release() { return false; } -private: - PyObject* m_ret; -}; - -#endif +#ifndef __PYOPS_BASE_ +#define __PYOPS_BASE_ + + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +using namespace std; + + +#ifdef _WIN32 +#define SAFE_SPRINTF _snprintf_s +#else +#define SAFE_SPRINTF snprintf +#endif + + + +//! 获取python异常信息 +struct pyops_t +{ + static int traceback(string& ret_); +}; +struct cpp_void_t{}; + +//! 用于抽取类型、类型对应的引用 +template +struct type_ref_traits_t; + +//! 用于python 可选参数 +template +struct pyoption_t +{ + typedef typename type_ref_traits_t::value_t value_t; + pyoption_t():m_set_flag(false){} + bool is_set() const { return m_set_flag;} + void set() { m_set_flag = true;} + value_t& value() { return m_value;} + const value_t& value() const{ return m_value;} + + const value_t& value(const value_t& default_) + { + if (is_set()) + return m_value; + else + return default_; + } + bool m_set_flag; + value_t m_value; +}; +//! 用于判断是否是可选参数 +template +struct pyoption_traits_t; + +//! pytype_traits_t 封装 PyLong_FromLong 相关的操作,用于为调用python生成参数 +template +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const char* const val_) + { + return PyString_FromString(val_); + } + /* + static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) + { + if (true == PyString_Check(pvalue_)) + { + m_ret = PyString_AsString(pvalue_); + return 0; + } + return -1; + } + */ + static const char* get_typename() { return "string";} +}; + +//! 用于调用python函数,生成tuple类型的python函数参数的工具类 +struct pycall_arg_t +{ + pycall_arg_t(int arg_num): + arg_index(0), + pargs_tuple(PyTuple_New(arg_num)) + {} + ~pycall_arg_t() + { + release(); + } + PyObject * get_args() const + { + return pargs_tuple; + } + template + pycall_arg_t& add(const T& val_) + { + if (arg_index < PyTuple_Size(pargs_tuple)) + { + PyObject* tmp_arg = pytype_traits_t::pyobj_from_cppobj(val_); + PyTuple_SetItem(pargs_tuple, arg_index, tmp_arg); + ++arg_index; + } + return *this; + } + void release() + { + if (pargs_tuple) + { + Py_DECREF(pargs_tuple); + pargs_tuple = NULL; + } + } + int arg_index; + PyObject * pargs_tuple; +}; + +//! 用于调用python函数,获取返回值的工具类 +class pytype_tool_t +{ +public: + virtual ~pytype_tool_t(){}; + virtual int parse_value(PyObject *pvalue_) = 0; + virtual const char* return_type() {return "";} + virtual bool need_release() { return false; } +}; + +//! 用于调用python函数,获取返回值的工具泛型类 +template +class pytype_tool_impl_t; +//! 封装调用python函数的C API +struct pycall_t +{ + static int call_func(PyObject *pModule, const string& mod_name_, const string& func_name_, + pycall_arg_t& pyarg_, pytype_tool_t& pyret_, string& err_) + { + PyObject *pFunc = PyObject_GetAttrString(pModule, func_name_.c_str()); + if (pFunc && PyCallable_Check(pFunc)) { + PyObject *pArgs = pyarg_.get_args(); + PyObject *pValue = PyObject_CallObject(pFunc, pArgs); + pyarg_.release();//! 等价于Py_DECREF(pArgs); + + if (pValue != NULL) { + if (pyret_.parse_value(pValue)) + { + err_ += "value returned is not "; + err_ += pyret_.return_type(); + err_ += string(" ") + func_name_ + " in " + mod_name_; + } + if (pyret_.need_release()){ + Py_DECREF(pValue); + } + } + } + else + { + err_ += "Cannot find function "; + err_ += func_name_ + " in " + mod_name_ + ","; + } + + Py_XDECREF(pFunc); + if (PyErr_Occurred()) + { + pyops_t::traceback(err_); + return 0; + } + return 0; + } + static int call_func_obj(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_t& pyret_, string& err_) + { + if (pFunc && PyCallable_Check(pFunc)) { + PyObject *pArgs = pyarg_.get_args(); + PyObject *pValue = PyObject_CallObject(pFunc, pArgs); + pyarg_.release();//! 等价于Py_DECREF(pArgs); + + if (pValue != NULL) { + if (pyret_.parse_value(pValue)) + { + err_ += "value returned is not "; + err_ += pyret_.return_type(); + } + if (pyret_.need_release()){ + Py_DECREF(pValue); + } + } + } + else + { + err_ += "invalid function"; + } + + if (PyErr_Occurred()) + { + pyops_t::traceback(err_); + return 0; + } + return 0; + } + template + static const T& call(const string& mod_name_, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); + template + static const T& call_obj_method(PyObject *pObj, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); + template + static const T& call_lambda(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); +}; +//! 用于扩展python的工具类,用来解析参数 +struct pyext_tool_t; + + +template +struct pyext_return_tool_t; + +//! 用于扩展python,生成pyobject类型的返回值给python +template +struct pyext_func_traits_t; + +//! 用于扩展python,traits出注册给python的函数接口 +#ifndef PYCTOR +#define PYCTOR int (*) +#endif +//! 表示void类型,由于void类型不能return,用void_ignore_t适配 +template +struct void_ignore_t; + +template +struct void_ignore_t +{ + typedef T value_t; +}; + +template<> +struct void_ignore_t +{ + typedef cpp_void_t value_t; +}; + +#define RET_V typename void_ignore_t::value_t + +//! 记录各个基类和子类的相互关系 +struct cpp_to_pyclass_reg_info_t +{ + struct inherit_info_t + { + inherit_info_t():pytype_def(NULL){} + PyTypeObject* pytype_def; + string inherit_name; + set all_child; + }; + typedef map inherit_info_map_t; + static inherit_info_map_t& get_all_info() + { + static inherit_info_map_t inherit_info; + return inherit_info; + } + + static void add(const string& child_, const string& base_, PyTypeObject* def_) + { + inherit_info_t tmp; + tmp.inherit_name = base_; + tmp.pytype_def = def_; + get_all_info()[child_] = tmp; + get_all_info()[base_].all_child.insert(def_); + } + static bool is_instance(PyObject* pysrc, const string& class_) + { + inherit_info_map_t& inherit_info = get_all_info(); + inherit_info_t& tmp = inherit_info[class_]; + if (tmp.pytype_def && PyObject_TypeCheck(pysrc, tmp.pytype_def)) + { + return true; + } + for (set::iterator it = tmp.all_child.begin(); it != tmp.all_child.end(); ++it) + { + if (*it && PyObject_TypeCheck(pysrc, *it)) + { + return true; + } + } + + return false; + } + +}; + + +//! 记录C++ class 对应到python中的名称、参数信息等,全局 +struct static_pytype_info_t +{ + string class_name; + string mod_name; + int total_args_num; + PyTypeObject* pytype_def; +}; + +//! 工具类,用于生成分配python class的接口,包括分配、释放 +template +struct pyclass_base_info_t +{ + struct obj_data_t + { + obj_data_t():obj(NULL){} + + PyObject_HEAD; + T* obj; + bool forbid_release; + void disable_auto_release(){ forbid_release = true; } + void release() + { + if (obj) + { + delete obj; + obj = NULL; + } + } + }; + + static void free_obj(obj_data_t* self) + { + if (false == self->forbid_release && self->obj) + { + self->release(); + } + self->ob_type->tp_free((PyObject*)self); + } + + static PyObject *alloc_obj(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + obj_data_t *self = (obj_data_t *)type->tp_alloc(type, 0); + return (PyObject *)self; + } + static PyObject *release(PyTypeObject *type, PyObject *args) + { + obj_data_t *self = (obj_data_t *)type; + self->release(); + return Py_BuildValue("i", 1); + } + static static_pytype_info_t pytype_info; +}; +template +static_pytype_info_t pyclass_base_info_t::pytype_info; + +//! 方便生成pyclass 初始化函数 +template +struct pyclass_ctor_tool_t; + +//! used to gen method of py class +template +struct pyclass_method_gen_t; + +//! 防止出现指针为NULL调用出错 +#define NULL_PTR_GUARD(X) if (NULL == X) {PyErr_SetString(PyExc_TypeError, "obj data ptr NULL");return NULL;} + +//! 用于生成python 的getter和setter接口,适配于c++ class的成员变量 +template +struct pyclass_member_func_gen_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + typedef RET CLASS_TYPE::* property_ptr_t; + + static PyObject *getter_func(obj_data_t *self, void *closure) + { + property_ptr_t property_ptr; + ::memcpy((void*)&property_ptr, (const void*)&closure, sizeof(closure)); + NULL_PTR_GUARD(self->obj); + CLASS_TYPE* p = self->obj; + return pytype_traits_t::pyobj_from_cppobj(p->*property_ptr); + } + static int setter_func(obj_data_t *self, PyObject *value, void *closure) + { + property_ptr_t property_ptr; + ::memcpy((void*)&property_ptr, (const void*)&closure, sizeof(closure)); + CLASS_TYPE* p = self->obj; + + return pytype_traits_t::pyobj_to_cppobj(value, p->*property_ptr); + } +}; + +//! 用于C++ 注册class的工具类,会记录class对应的名称、成员方法、成员变量 +class pyclass_regigster_tool_t +{ +public: + struct method_info_t + { + PyCFunction func; + string func_name; + string func_real_name; + string doc; + string doc_real; + int args_num; + int option_args_num; + long func_addr; + }; + struct property_info_t + { + void* ptr; + string property_name; + string doc; + getter getter_func; + setter setter_func; + }; + virtual ~pyclass_regigster_tool_t(){} + + typedef PyObject *(*pyobj_alloc_t)(PyTypeObject*, PyObject*, PyObject*); + + string class_name; + string class_real_name; + string class_name_with_mod; + string class_reel_name_with_mod; + string inherit_name; + int type_size; + string doc; + int args_num; + int option_args_num; + destructor dector; + initproc init; + pyobj_alloc_t ctor; + + //! member functions + PyCFunction delete_func; + vector methods_info; + //! property + vector propertys_info; + //! for init module + PyTypeObject pytype_def; + //! method + vector pymethod_def; + //! property + vector pyproperty_def; + + //! 静态类型需要全局记录该类型被注册成神马python 类型 + static_pytype_info_t* static_pytype_info; + + template + pyclass_regigster_tool_t& reg(FUNC f_, const string& func_name_, string doc_ = "") + { + method_info_t tmp; + tmp.func_name = func_name_; + tmp.func_real_name = func_name_ + "_internal_"; + tmp.doc = doc_; + tmp.doc_real = "internal use"; + tmp.func = (PyCFunction)pyclass_method_gen_t::pymethod; + tmp.args_num = pyclass_method_gen_t::args_num(); + tmp.option_args_num = pyclass_method_gen_t::option_args_num(); + ::memcpy((void*)&tmp.func_addr, (const void*)&f_, sizeof(void*)); + methods_info.push_back(tmp); + return *this; + } + template + pyclass_regigster_tool_t& reg_property(RET CLASS_TYPE::* member_, const string& member_name_, string doc_ = "") + { + property_info_t tmp; + ::memcpy((void*)&tmp.ptr, (const void*)&member_, sizeof(member_)); + tmp.property_name = member_name_; + tmp.doc = doc_; + tmp.getter_func = (getter)pyclass_member_func_gen_t::getter_func; + tmp.setter_func = (setter)pyclass_member_func_gen_t::setter_func; + propertys_info.push_back(tmp); + return *this; + } +}; + + +template +struct type_ref_traits_t +{ + typedef T value_t; + typedef T& ref_t; + value_t value; +}; +template +struct type_ref_traits_t +{ + typedef T value_t; + typedef T& ref_t; + value_t value; +}; +template +struct type_ref_traits_t +{ + typedef T value_t; + typedef T& ref_t; + value_t value; +}; +//! 用于判断是否是可选参数 +template +struct pyoption_traits_t +{ + static int is() { return 0;} +}; +template +struct pyoption_traits_t > +{ + static int is() { return 1;} +}; + + +template<>//typename T> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const long& val_) + { + return PyLong_FromLong(long(val_)); + } + static int pyobj_to_cppobj(PyObject *pvalue_, long& m_ret) + { + if (true == PyLong_Check(pvalue_)) + { + m_ret = (long)PyLong_AsLong(pvalue_); + return 0; + } + else if (true == PyInt_Check(pvalue_)) + { + m_ret = (long)PyInt_AsLong(pvalue_); + return 0; + } + return -1; + } + static const char* get_typename() { return "long";} +}; + +#define IMPL_INT_CODE(X) \ +template<> \ +struct pytype_traits_t \ +{ \ + static PyObject* pyobj_from_cppobj(const X& val_) \ + { \ + return PyInt_FromLong(long(val_)); \ + } \ + static int pyobj_to_cppobj(PyObject *pvalue_, X& m_ret) \ + { \ + if (true == PyLong_Check(pvalue_)) \ + { \ + m_ret = (X)PyLong_AsLong(pvalue_); \ + return 0; \ + } \ + else if (true == PyInt_Check(pvalue_)) \ + { \ + m_ret = (X)PyInt_AsLong(pvalue_); \ + return 0; \ + } \ + return -1; \ + } \ + static const char* get_typename() { return #X;} \ +}; + +IMPL_INT_CODE(int) +IMPL_INT_CODE(unsigned int) +IMPL_INT_CODE(short) +IMPL_INT_CODE(unsigned short) +IMPL_INT_CODE(char) +IMPL_INT_CODE(unsigned char) + +#ifdef _WIN32 +IMPL_INT_CODE(unsigned long) +#else +#ifndef __x86_64__ +IMPL_INT_CODE(int64_t) +#endif +IMPL_INT_CODE(uint64_t) +#endif + +template +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const T* val_) + { + const string& mod_name = pyclass_base_info_t::pytype_info.mod_name; + const string& class_name = pyclass_base_info_t::pytype_info.class_name; + PyObject *pName = NULL, *pModule = NULL, *pValue = NULL; + + if (class_name.empty()) + return pytype_traits_t::pyobj_from_cppobj(long(val_)); + + pName = PyString_FromString(mod_name.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + if (PyErr_Occurred()) + PyErr_Print(); + fprintf(stderr, "Failed to load \"%s\"\n", mod_name.c_str()); + assert(NULL && "this can not be happened"); + return NULL; + } + PyObject *pyclass = PyObject_GetAttrString(pModule, class_name.c_str()); + if (pyclass && PyCallable_Check(pyclass)) { + PyObject *pArgs = PyTuple_New(pyclass_base_info_t::pytype_info.total_args_num+1); + for (int i = 0; i< pyclass_base_info_t::pytype_info.total_args_num; ++i) + { + PyTuple_SetItem(pArgs, i, pytype_traits_t::pyobj_from_cppobj(0)); + } + + PyObject *palloc = pyclass_base_info_t::alloc_obj(pyclass_base_info_t::pytype_info.pytype_def, NULL, NULL); + typename pyclass_base_info_t::obj_data_t* pdest_obj = (typename pyclass_base_info_t::obj_data_t*)palloc; + //pdest_obj->obj = val_; + ::memcpy((void*)&pdest_obj->obj, (const void*)&val_, sizeof(pdest_obj->obj)); + pdest_obj->disable_auto_release(); + PyTuple_SetItem(pArgs, pyclass_base_info_t::pytype_info.total_args_num, palloc); + pValue = PyObject_CallObject(pyclass, pArgs); + Py_XDECREF(pArgs); + } + + Py_XDECREF(pyclass); + Py_DECREF(pModule); + return pValue; + } + + static int pyobj_to_cppobj(PyObject *pvalue_, T*& m_ret) + { + PyObject *pysrc = PyObject_GetAttrString(pvalue_, "obj"); + //!PyObject_TypeCheck(pysrc, pyclass_base_info_t::pytype_info.pytype_def)) { + if (NULL == pysrc || false == cpp_to_pyclass_reg_info_t::is_instance(pysrc, pyclass_base_info_t::pytype_info.class_name)) + { + Py_XDECREF(pysrc); + return -1; + } + typename pyclass_base_info_t::obj_data_t* pdest_obj = (typename pyclass_base_info_t::obj_data_t*)pysrc; + + m_ret = pdest_obj->obj; + Py_XDECREF(pysrc); + return 0; + } + + static const char* get_typename() { return pyclass_base_info_t::pytype_info.class_name.c_str();} +}; + +template +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(T* val_) + { + return pytype_traits_t::pyobj_from_cppobj(val_); + } + static int pyobj_to_cppobj(PyObject *pvalue_,T*& m_ret) + { + return pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret); + } + static const char* get_typename() { return pyclass_base_info_t::pytype_info.class_name.c_str();} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(PyObject* val_) + { + return val_; + } + static int pyobj_to_cppobj(PyObject *pvalue_, PyObject*& m_ret) + { + m_ret = pvalue_; + return 0; + } + static const char* get_typename() { return "PyObject";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const char* const val_) + { + return PyString_FromString(val_); + } + /* + static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) + { + if (true == PyString_Check(pvalue_)) + { + m_ret = PyString_AsString(pvalue_); + return 0; + } + return -1; + } + */ + static const char* get_typename() { return "string";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const char*& val_) + { + return PyString_FromString(val_); + } + /* + static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) + { + if (true == PyString_Check(pvalue_)) + { + m_ret = PyString_AsString(pvalue_); + return 0; + } + return -1; + } + */ + static const char* get_typename() { return "string";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(bool val_) + { + if (val_) + { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; + } + static int pyobj_to_cppobj(PyObject *pvalue_, bool& m_ret) + { + if (Py_False == pvalue_|| Py_None == pvalue_) + { + m_ret = false; + } + else + { + m_ret = true; + } + return 0; + } + static const char* get_typename() { return "bool";} +}; + +template +struct pytype_traits_t > +{ + static int pyobj_to_cppobj(PyObject *pvalue_, pyoption_t& m_ret) + { + if (Py_None == pvalue_) + { + return 0; + } + else if (0 == pytype_traits_t::value_t>::pyobj_to_cppobj(pvalue_, m_ret.value())) + { + m_ret.set(); + return 0; + } + return -1; + } + static const char* get_typename() { return "pyoption_t";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const string& val_) + { + return PyString_FromStringAndSize(val_.c_str(), val_.size()); + } + static int pyobj_to_cppobj(PyObject *pvalue_, string& m_ret) + { + if (true == PyString_Check(pvalue_)) + { + char* pDest = NULL; + Py_ssize_t nLen = 0; + PyString_AsStringAndSize(pvalue_, &pDest, &nLen); + + m_ret.assign(pDest, nLen); + return 0; + } + else if (true == PyUnicode_Check(pvalue_)) + { + char* pDest = NULL; + Py_ssize_t nLen = 0; + PyString_AsStringAndSize(pvalue_, &pDest, &nLen); + m_ret.assign(pDest, nLen); + return 0; + /* +#ifdef _WIN32 + PyObject* retStr = PyUnicode_AsEncodedString(pvalue_, "gbk", ""); +#else + PyObject* retStr = PyUnicode_AsUTF8String(pvalue_); +#endif + if (retStr) + { + m_ret = PyString_AsString(retStr); + Py_XDECREF(retStr); + return 0; + } + */ + } + return -1; + } + static const char* get_typename() { return "string";} +}; + +#ifdef _WIN32 +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(const wstring& wstr) + { + return PyUnicode_FromWideChar(wstr.c_str(), wstr.length()); + } + static int pyobj_to_cppobj(PyObject *pvalue_, wstring& wstr_ret) + { + if (true == PyString_Check(pvalue_)) + { + PyObject* retStr = PyUnicode_FromObject(pvalue_); + if (retStr) + { + int n = PyUnicode_GetSize(retStr); + wstr_ret.resize(n); + n = PyUnicode_AsWideChar((PyUnicodeObject*)retStr, &(wstr_ret[0]), n); + Py_XDECREF(retStr); + return 0; + } + return 0; + } + else if (true == PyUnicode_Check(pvalue_)) + { + int n = PyUnicode_GetSize(pvalue_); + wstr_ret.resize(n); + n = PyUnicode_AsWideChar((PyUnicodeObject*)pvalue_, &(wstr_ret[0]), n); + return 0; + } + return -1; + } + static const char* get_typename() { return "wstring";} +}; +#endif + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(float val_) + { + return PyFloat_FromDouble(double(val_)); + } + static int pyobj_to_cppobj(PyObject *pvalue_, float& m_ret) + { + if (true == PyFloat_Check(pvalue_)) + { + m_ret = (float)PyFloat_AsDouble(pvalue_); + return 0; + } + return -1; + } + static const char* get_typename() { return "float";} +}; + +template<> +struct pytype_traits_t +{ + static PyObject* pyobj_from_cppobj(double val_) + { + return PyFloat_FromDouble(val_); + } + static int pyobj_to_cppobj(PyObject *pvalue_, double& m_ret) + { + if (true == PyFloat_Check(pvalue_)) + { + m_ret = PyFloat_AsDouble(pvalue_); + return 0; + } + return -1; + } + static const char* get_typename() { return "double";} +}; + +template +struct pytype_traits_t > +{ + static PyObject* pyobj_from_cppobj(const vector& val_) + { + PyObject* ret = PyList_New(val_.size()); + for (size_t i = 0; i < val_.size(); ++i) + { + PyList_SetItem(ret, i, pytype_traits_t::pyobj_from_cppobj(val_[i])); + } + return ret; + } + static int pyobj_to_cppobj(PyObject *pvalue_, vector& m_ret) + { + m_ret.clear(); + if (true == PyTuple_Check(pvalue_)) + { + int n = PyTuple_Size(pvalue_); + for (int i = 0; i < n; ++i) + { + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyTuple_GetItem(pvalue_, i))) + { + return -1; + } + m_ret.push_back(ret_tool.get_value()); + } + return 0; + } + else if (true == PyList_Check(pvalue_)) + { + int n = PyList_Size(pvalue_); + for (int i = 0; i < n; ++i) + { + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyList_GetItem(pvalue_, i))) + { + return -1; + } + m_ret.push_back(ret_tool.get_value()); + } + return 0; + } + return -1; + } + static const char* get_typename() { return "vector";} +}; +template +struct pytype_traits_t > +{ + static PyObject* pyobj_from_cppobj(const list& val_) + { + size_t n = val_.size(); + PyObject* ret = PyList_New(n); + int i = 0; + for (typename list::const_iterator it = val_.begin(); it != val_.end(); ++it) + { + PyList_SetItem(ret, i++, pytype_traits_t::pyobj_from_cppobj(*it)); + } + return ret; + } + static int pyobj_to_cppobj(PyObject *pvalue_, list& m_ret) + { + pytype_tool_impl_t ret_tool; + if (true == PyTuple_Check(pvalue_)) + { + int n = PyTuple_Size(pvalue_); + for (int i = 0; i < n; ++i) + { + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyTuple_GetItem(pvalue_, i))) + { + return -1; + } + m_ret.push_back(ret_tool.get_value()); + } + return 0; + } + else if (true == PyList_Check(pvalue_)) + { + int n = PyList_Size(pvalue_); + for (int i = 0; i < n; ++i) + { + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyList_GetItem(pvalue_, i))) + { + return -1; + } + m_ret.push_back(ret_tool.get_value()); + } + return 0; + } + return -1; + } + static const char* get_typename() { return "list";} +}; +template +struct pytype_traits_t > +{ + static PyObject* pyobj_from_cppobj(const set& val_) + { + PyObject* ret = PySet_New(NULL); + for (typename set::const_iterator it = val_.begin(); it != val_.end(); ++it) + { + PyObject *v = pytype_traits_t::pyobj_from_cppobj(*it); + PySet_Add(ret, v); + Py_DECREF(v); + } + return ret; + } + static int pyobj_to_cppobj(PyObject *pvalue_, set& m_ret) + { + m_ret.clear(); + pytype_tool_impl_t ret_tool; + PyObject *iter = PyObject_GetIter(pvalue_); + PyObject *item = NULL; + while (NULL != iter && NULL != (item = PyIter_Next(iter))) + { + T tmp(); + if (pytype_traits_t::pyobj_to_cppobj(item, tmp)) + { + Py_DECREF(item); + Py_DECREF(iter); + return -1; + } + m_ret.insert(tmp); + Py_DECREF(item); + } + if (iter) + { + Py_DECREF(iter); + return 0; + } + return -1; + } + static const char* get_typename() { return "set";} +}; +template +struct pytype_traits_t > +{ + static PyObject* pyobj_from_cppobj(const map& val_) + { + PyObject* ret = PyDict_New(); + for (typename map::const_iterator it = val_.begin(); it != val_.end(); ++it) + { + PyObject *k = pytype_traits_t::pyobj_from_cppobj(it->first); + PyObject *v = pytype_traits_t::pyobj_from_cppobj(it->second); + PyDict_SetItem(ret, k, v); + Py_DECREF(k); + Py_DECREF(v); + } + return ret; + } + static int pyobj_to_cppobj(PyObject *pvalue_, map& m_ret) + { + m_ret.clear(); + pytype_tool_impl_t ret_tool_T; + pytype_tool_impl_t ret_tool_R; + if (true == PyDict_Check(pvalue_)) + { + PyObject *key = NULL, *value = NULL; + Py_ssize_t pos = 0; + + while (PyDict_Next(pvalue_, &pos, &key, &value)) + { + T tmp_key; + R tmp_value; + if (pytype_traits_t::pyobj_to_cppobj(key, tmp_key) || + pytype_traits_t::pyobj_to_cppobj(value, tmp_value)) + { + return -1; + } + m_ret[tmp_key] = tmp_value; + } + return 0; + } + return -1; + } + static const char* get_typename() { return "map";} +}; + +//! ��ȡpython�����ķ���ֵ,������ +template +class pytype_tool_impl_t: public pytype_tool_t +{ +public: + pytype_tool_impl_t():m_ret(){} + + virtual int parse_value(PyObject *pvalue_) + { + if (pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret)) + { + return -1; + } + return 0; + } + + const T& get_value() const { return m_ret; } + virtual const char* return_type() {return pytype_traits_t::get_typename();} +private: + T m_ret; +}; + +template<> +class pytype_tool_impl_t: public pytype_tool_t +{ +public: + pytype_tool_impl_t():m_ret(){} + + virtual int parse_value(PyObject *pvalue_) + { + return 0; + } + + const cpp_void_t& get_value() const { return m_ret; } + virtual const char* return_type() { return "void";} +private: + cpp_void_t m_ret; +}; +template +class pytype_tool_impl_t: public pytype_tool_t +{ +public: + pytype_tool_impl_t():m_ret(){} + + virtual int parse_value(PyObject *pvalue_) + { + if (pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret)) + { + return -1; + } + return 0; + } + + T* get_value() const { return m_ret; } +private: + T* m_ret; +}; + + +template<> +class pytype_tool_impl_t: public pytype_tool_t +{ +public: + pytype_tool_impl_t():m_ret(){} + + virtual int parse_value(PyObject *pvalue_) + { + m_ret = pvalue_; + return 0; + } + + PyObject*& get_value() { return m_ret; } + bool need_release() { return false; } +private: + PyObject* m_ret; +}; + +#endif diff --git a/python2.7/VersionForRead/pyops_for_embed.h b/oldversion/python2.7/VersionForRead/pyops_for_embed.h similarity index 95% rename from python2.7/VersionForRead/pyops_for_embed.h rename to oldversion/python2.7/VersionForRead/pyops_for_embed.h index e91a7f3..b3c734f 100644 --- a/python2.7/VersionForRead/pyops_for_embed.h +++ b/oldversion/python2.7/VersionForRead/pyops_for_embed.h @@ -1,77 +1,77 @@ -#ifndef __PYOPS_FOR_EMBED -#define __PYOPS_FOR_EMBED - -#include "pyops_base.h" - - - - - -template -const T& pycall_t::call(const string& mod_name_, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) -{ - PyObject *pName = NULL, *pModule = NULL; - string err_msg; - - pName = PyString_FromString(mod_name_.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - return pyret.get_value(); - } - - call_func(pModule, mod_name_, func_name_, pyarg_, pyret, err_msg); - Py_DECREF(pModule); - - if (!err_msg.empty()) - { - throw runtime_error(err_msg.c_str()); - } - return pyret.get_value(); -} -template -const T& pycall_t::call_obj_method(PyObject *pObj, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) -{ - string err_msg; - if (NULL == pObj) - { - pyops_t::traceback(err_msg); - throw runtime_error(err_msg.c_str()); - return pyret.get_value(); - } - - static string mod_name_ = "NaN"; - call_func(pObj, mod_name_, func_name_, pyarg_, pyret, err_msg); - - if (!err_msg.empty()) - { - throw runtime_error(err_msg.c_str()); - } - return pyret.get_value(); -} - -template -const T& pycall_t::call_lambda(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) -{ - string err_msg; - if (NULL == pFunc) - { - err_msg = "can not call null PyObject"; - throw runtime_error(err_msg.c_str()); - return pyret.get_value(); - } - - call_func_obj(pFunc, pyarg_, pyret, err_msg); - - if (!err_msg.empty()) - { - throw runtime_error(err_msg.c_str()); - } - return pyret.get_value(); -} - - -#endif +#ifndef __PYOPS_FOR_EMBED +#define __PYOPS_FOR_EMBED + +#include "pyops_base.h" + + + + + +template +const T& pycall_t::call(const string& mod_name_, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) +{ + PyObject *pName = NULL, *pModule = NULL; + string err_msg; + + pName = PyString_FromString(mod_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return pyret.get_value(); + } + + call_func(pModule, mod_name_, func_name_, pyarg_, pyret, err_msg); + Py_DECREF(pModule); + + if (!err_msg.empty()) + { + throw runtime_error(err_msg.c_str()); + } + return pyret.get_value(); +} +template +const T& pycall_t::call_obj_method(PyObject *pObj, const string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) +{ + string err_msg; + if (NULL == pObj) + { + pyops_t::traceback(err_msg); + throw runtime_error(err_msg.c_str()); + return pyret.get_value(); + } + + static string mod_name_ = "NaN"; + call_func(pObj, mod_name_, func_name_, pyarg_, pyret, err_msg); + + if (!err_msg.empty()) + { + throw runtime_error(err_msg.c_str()); + } + return pyret.get_value(); +} + +template +const T& pycall_t::call_lambda(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) +{ + string err_msg; + if (NULL == pFunc) + { + err_msg = "can not call null PyObject"; + throw runtime_error(err_msg.c_str()); + return pyret.get_value(); + } + + call_func_obj(pFunc, pyarg_, pyret, err_msg); + + if (!err_msg.empty()) + { + throw runtime_error(err_msg.c_str()); + } + return pyret.get_value(); +} + + +#endif diff --git a/python2.7/VersionForRead/pyops_for_extend.h b/oldversion/python2.7/VersionForRead/pyops_for_extend.h similarity index 97% rename from python2.7/VersionForRead/pyops_for_extend.h rename to oldversion/python2.7/VersionForRead/pyops_for_extend.h index e91ca90..aa6cc88 100644 --- a/python2.7/VersionForRead/pyops_for_extend.h +++ b/oldversion/python2.7/VersionForRead/pyops_for_extend.h @@ -1,1745 +1,1745 @@ -#ifndef __PYOPS_FOR_EXTEND_ -#define __PYOPS_FOR_EXTEND_ - -#include "pyops_base.h" - - - -//! 用于扩展python的工具类,用来解析参数 -struct pyext_tool_t -{ - pyext_tool_t(PyObject* args_): - m_args(args_), - m_arg_tuple(NULL), - m_index(0), - m_err(false), - m_func_addr(0) - { - if (!PyArg_ParseTuple(args_, "lO", &m_func_addr, &m_arg_tuple)) { - m_err = true; - return; - } - if (NULL == m_arg_tuple || false == PyTuple_Check(m_arg_tuple)) - { - PyErr_SetString(PyExc_TypeError, "arg type invalid(shoule func_name, args tuple)"); - m_err = true; - return; - } - m_size = PyTuple_Size(m_arg_tuple); - } - - template - pyext_tool_t& parse_arg(T& ret_arg_) - { - typedef typename type_ref_traits_t::value_t value_t; - if (false == m_err) - { - if (m_index >= m_size) - { - stringstream ss; - ss << "param num invalid, only["<< m_index + 1 <<"] provided"; - PyErr_SetString(PyExc_TypeError, ss.str().c_str()); - m_err = true; - return *this; - } - - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyTuple_GetItem(m_arg_tuple, m_index))) - { - stringstream ss; - ss << "param[" << m_index + 1 << "] type invalid, "<< pytype_traits_t::get_typename() << " needed"; - PyErr_SetString(PyExc_TypeError, ss.str().c_str()); - m_err = true; - return *this; - } - ++m_index; - ret_arg_ = ret_tool.get_value(); - } - return *this; - } - - bool is_err() const { return m_err;} - long get_func_addr() const { return m_func_addr;} - - template - FUNC get_func_ptr() const - { - FUNC f = NULL; - ::memcpy((void*)&f, (const void*)&m_func_addr, sizeof(m_func_addr)); - return f; - } - PyObject* m_args; - PyObject* m_arg_tuple; - int m_index; - int m_size; - bool m_err;//! 是否异常 - long m_func_addr; -}; - - - -//! 用于扩展python,生成pyobject类型的返回值给python -template -struct pyext_return_tool_t -{ - //! 用于静态方法 - template - static PyObject* route_call(F f) - { - return pytype_traits_t::pyobj_from_cppobj(f()); - } - template - static PyObject* route_call(F f, ARG1& a1) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value, a8.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value, a8.value, a9.value)); - } - //! 用于成员方法 - template - static PyObject* route_method_call(O o, F f) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)()); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value, a8.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value, a8.value, a9.value)); - } -}; - - -template<> -struct pyext_return_tool_t -{ - template - static PyObject* route_call(F f) - { - f(); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1) - { - f(a1.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2) - { - f(a1.value, a2.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3) - { - f(a1.value, a2.value, a3.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) - { - f(a1.value, a2.value, a3.value, a4.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f) - { - (o->*f)(); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1) - { - (o->*f)(a1.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2) - { - (o->*f)(a1.value, a2.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3) - { - (o->*f)(a1.value, a2.value, a3.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); - Py_RETURN_NONE; - } -}; - - - -//! 用于扩展python,traits出注册给python的函数接口 -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(); - static int args_num() { return 0;} - static int option_args_num() { return 0;} - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - return pyext_return_tool_t::route_call(f); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1); - static int args_num(){ return 1-option_args_num();} - static int option_args_num() - { - return pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - if (pyext_tool.parse_arg(a1.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2); - static int args_num() { return 2 - option_args_num();} - static int option_args_num() - { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3); - static int args_num() { return 3-option_args_num();} - static int option_args_num() - { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3); - } -}; -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4); - static int args_num() { return 4-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5); - static int args_num() { return 5-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); - static int args_num() { return 6-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); - static int args_num() { return 7-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); - static int args_num() { return 8-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7, a8); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); - static int args_num() { return 9-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - type_ref_traits_t a9; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7, a8, a9); - } -}; - -//! ��������pyclass ��ʼ������ -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - - self->obj = new CLASS_TYPE(); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - if (pyext_tool.parse_arg(a1.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - type_ref_traits_t a9; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); - return 0; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(); - static int args_num() { return 0;} - static int option_args_num() { return 0;} - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1); - static int args_num() { return 1-option_args_num();} - static int option_args_num() { return pyoption_traits_t::value_t>::is();} - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - if (pyext_tool.parse_arg(a1.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2); - static int args_num() { return 2-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2);; - } -}; - - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3); - static int args_num() { return 3-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4); - static int args_num() { return 4-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5); - static int args_num() { return 5-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); - static int args_num() { return 6-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); - static int args_num() { return 7-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); - static int args_num() { return 8-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8);; - } -}; - - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); - static int args_num() { return 9-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - type_ref_traits_t a9; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8, a9);; - } -}; - -//! const类型成员函数--------------------------------------------------------------------------------------------- - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)() const; - static int args_num() { return 0;} - static int option_args_num() { return 0;} - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1) const; - static int args_num() { return 1-option_args_num();} - static int option_args_num() { return pyoption_traits_t::value_t>::is();} - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - if (pyext_tool.parse_arg(a1.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2) const; - static int args_num() { return 2-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2);; - } -}; - - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3) const; - static int args_num() { return 3-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4) const; - static int args_num() { return 4-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5) const; - static int args_num() { return 5-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) const; - static int args_num() { return 6-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) const; - static int args_num() { return 7-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8) const; - static int args_num() { return 8-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8);; - } -}; - - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9) const; - static int args_num() { return 9-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - type_ref_traits_t a9; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8, a9);; - } -}; - - -#endif +#ifndef __PYOPS_FOR_EXTEND_ +#define __PYOPS_FOR_EXTEND_ + +#include "pyops_base.h" + + + +//! 用于扩展python的工具类,用来解析参数 +struct pyext_tool_t +{ + pyext_tool_t(PyObject* args_): + m_args(args_), + m_arg_tuple(NULL), + m_index(0), + m_err(false), + m_func_addr(0) + { + if (!PyArg_ParseTuple(args_, "lO", &m_func_addr, &m_arg_tuple)) { + m_err = true; + return; + } + if (NULL == m_arg_tuple || false == PyTuple_Check(m_arg_tuple)) + { + PyErr_SetString(PyExc_TypeError, "arg type invalid(shoule func_name, args tuple)"); + m_err = true; + return; + } + m_size = PyTuple_Size(m_arg_tuple); + } + + template + pyext_tool_t& parse_arg(T& ret_arg_) + { + typedef typename type_ref_traits_t::value_t value_t; + if (false == m_err) + { + if (m_index >= m_size) + { + stringstream ss; + ss << "param num invalid, only["<< m_index + 1 <<"] provided"; + PyErr_SetString(PyExc_TypeError, ss.str().c_str()); + m_err = true; + return *this; + } + + pytype_tool_impl_t ret_tool; + if (ret_tool.parse_value(PyTuple_GetItem(m_arg_tuple, m_index))) + { + stringstream ss; + ss << "param[" << m_index + 1 << "] type invalid, "<< pytype_traits_t::get_typename() << " needed"; + PyErr_SetString(PyExc_TypeError, ss.str().c_str()); + m_err = true; + return *this; + } + ++m_index; + ret_arg_ = ret_tool.get_value(); + } + return *this; + } + + bool is_err() const { return m_err;} + long get_func_addr() const { return m_func_addr;} + + template + FUNC get_func_ptr() const + { + FUNC f = NULL; + ::memcpy((void*)&f, (const void*)&m_func_addr, sizeof(m_func_addr)); + return f; + } + PyObject* m_args; + PyObject* m_arg_tuple; + int m_index; + int m_size; + bool m_err;//! 是否异常 + long m_func_addr; +}; + + + +//! 用于扩展python,生成pyobject类型的返回值给python +template +struct pyext_return_tool_t +{ + //! 用于静态方法 + template + static PyObject* route_call(F f) + { + return pytype_traits_t::pyobj_from_cppobj(f()); + } + template + static PyObject* route_call(F f, ARG1& a1) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value, a8.value)); + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) + { + return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value, a8.value, a9.value)); + } + //! 用于成员方法 + template + static PyObject* route_method_call(O o, F f) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)()); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value, a8.value)); + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) + { + NULL_PTR_GUARD(o); + return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, + a7.value, a8.value, a9.value)); + } +}; + + +template<> +struct pyext_return_tool_t +{ + template + static PyObject* route_call(F f) + { + f(); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1) + { + f(a1.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2) + { + f(a1.value, a2.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3) + { + f(a1.value, a2.value, a3.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) + { + f(a1.value, a2.value, a3.value, a4.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); + Py_RETURN_NONE; + } + template + static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) + { + f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f) + { + (o->*f)(); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1) + { + (o->*f)(a1.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2) + { + (o->*f)(a1.value, a2.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3) + { + (o->*f)(a1.value, a2.value, a3.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); + Py_RETURN_NONE; + } + template + static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) + { + (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); + Py_RETURN_NONE; + } +}; + + + +//! 用于扩展python,traits出注册给python的函数接口 +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(); + static int args_num() { return 0;} + static int option_args_num() { return 0;} + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + return pyext_return_tool_t::route_call(f); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1); + static int args_num(){ return 1-option_args_num();} + static int option_args_num() + { + return pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + if (pyext_tool.parse_arg(a1.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2); + static int args_num() { return 2 - option_args_num();} + static int option_args_num() + { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3); + static int args_num() { return 3-option_args_num();} + static int option_args_num() + { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3); + } +}; +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4); + static int args_num() { return 4-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5); + static int args_num() { return 5-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); + static int args_num() { return 6-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); + static int args_num() { return 7-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); + static int args_num() { return 8-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7, a8); + } +}; + +template +struct pyext_func_traits_t +{ + typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); + static int args_num() { return 9-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is() + + pyoption_traits_t::value_t>::is(); + } + static PyObject* pyfunc(PyObject* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = (func_t)pyext_tool.get_func_addr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + type_ref_traits_t a9; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7, a8, a9); + } +}; + +//! ��������pyclass ��ʼ������ +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + + self->obj = new CLASS_TYPE(); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + if (pyext_tool.parse_arg(a1.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); + return 0; + } +}; + +template +struct pyclass_ctor_tool_t +{ + typedef typename pyclass_base_info_t::obj_data_t obj_data_t; + static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) + { + if (self->obj) return 0; + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return -1; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + type_ref_traits_t a9; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) + { + return -1; + } + self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); + return 0; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(); + static int args_num() { return 0;} + static int option_args_num() { return 0;} + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1); + static int args_num() { return 1-option_args_num();} + static int option_args_num() { return pyoption_traits_t::value_t>::is();} + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + if (pyext_tool.parse_arg(a1.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2); + static int args_num() { return 2-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2);; + } +}; + + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3); + static int args_num() { return 3-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4); + static int args_num() { return 4-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5); + static int args_num() { return 5-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); + static int args_num() { return 6-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); + static int args_num() { return 7-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); + static int args_num() { return 8-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8);; + } +}; + + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); + static int args_num() { return 9-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + type_ref_traits_t a9; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8, a9);; + } +}; + +//! const类型成员函数--------------------------------------------------------------------------------------------- + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)() const; + static int args_num() { return 0;} + static int option_args_num() { return 0;} + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1) const; + static int args_num() { return 1-option_args_num();} + static int option_args_num() { return pyoption_traits_t::value_t>::is();} + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + if (pyext_tool.parse_arg(a1.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2) const; + static int args_num() { return 2-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2);; + } +}; + + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3) const; + static int args_num() { return 3-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4) const; + static int args_num() { return 4-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5) const; + static int args_num() { return 5-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) const; + static int args_num() { return 6-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) const; + static int args_num() { return 7-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7);; + } +}; + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8) const; + static int args_num() { return 8-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8);; + } +}; + + +template +struct pyclass_method_gen_t +{ + typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9) const; + static int args_num() { return 9-option_args_num();} + static int option_args_num() { + return pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is()+ + pyoption_traits_t::value_t>::is(); + } + + static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) + { + pyext_tool_t pyext_tool(args); + if (pyext_tool.is_err()) + { + return NULL; + } + func_t f = pyext_tool.get_func_ptr(); + if (0 == f) + { + PyErr_SetString(PyExc_TypeError, "func address must provided"); + return NULL; + } + type_ref_traits_t a1; + type_ref_traits_t a2; + type_ref_traits_t a3; + type_ref_traits_t a4; + type_ref_traits_t a5; + type_ref_traits_t a6; + type_ref_traits_t a7; + type_ref_traits_t a8; + type_ref_traits_t a9; + if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) + .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) + { + return NULL; + } + return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8, a9);; + } +}; + + +#endif diff --git a/python2.7/ffpython.h b/oldversion/python2.7/ffpython.h similarity index 100% rename from python2.7/ffpython.h rename to oldversion/python2.7/ffpython.h From 808c1210b105e58ac7d57ac5bbc26e433ed0bc39 Mon Sep 17 00:00:00 2001 From: fanchy Date: Wed, 17 Jun 2020 20:58:24 +0800 Subject: [PATCH 10/13] del --- pyops_base.h | 1130 ---------------------------- pyops_for_embed.h | 77 -- pyops_for_extend.h | 1745 -------------------------------------------- 3 files changed, 2952 deletions(-) delete mode 100644 pyops_base.h delete mode 100644 pyops_for_embed.h delete mode 100644 pyops_for_extend.h diff --git a/pyops_base.h b/pyops_base.h deleted file mode 100644 index afa7add..0000000 --- a/pyops_base.h +++ /dev/null @@ -1,1130 +0,0 @@ -#ifndef __PYOPS_BASE_ -#define __PYOPS_BASE_ - - -#ifdef _DEBUG - #undef _DEBUG - #include - #define _DEBUG -#else - #include -#endif -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef _WIN32 -#define SAFE_SPRINTF _snprintf_s -#define PTR_NUMBER int64_t -#else -#define SAFE_SPRINTF snprintf -#define PTR_NUMBER int64_t -#endif - -#define PyString_Check PyUnicode_Check -#define PyString_AsString(pvalue_) PyUnicode_AsUTF8(pvalue_) -#define PyString_AsStringAndSize(pvalue_, pDestPtr, nLen) *pDestPtr = PyUnicode_AsUTF8AndSize(pvalue_, nLen) -#define PyString_FromStringAndSize PyUnicode_FromStringAndSize -#define PyString_FromString PyUnicode_FromString - - -//! 获取python异常信息 -struct pyops_t -{ - static int traceback(std::string& ret_); -}; -struct cpp_void_t{}; - -//! 用于抽取类型、类型对应的引用 -template -struct type_ref_traits_t; - -//! 用于python 可选参数 -template -struct pyoption_t -{ - typedef typename type_ref_traits_t::value_t value_t; - pyoption_t():m_set_flag(false){} - bool is_set() const { return m_set_flag;} - void set() { m_set_flag = true;} - value_t& value() { return m_value;} - const value_t& value() const{ return m_value;} - - const value_t& value(const value_t& default_) - { - if (is_set()) - return m_value; - else - return default_; - } - bool m_set_flag; - value_t m_value; -}; -//! 用于判断是否是可选参数 -template -struct pyoption_traits_t; - -//! pytype_traits_t 封装 PyLong_FromLong 相关的操作,用于为调用python生成参数 -template -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const char* const val_) - { - return PyString_FromString(val_); - } - /* - static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) - { - if (true == PyString_Check(pvalue_)) - { - m_ret = PyString_AsString(pvalue_); - return 0; - } - return -1; - } - */ - static const char* get_typename() { return "std::string";} -}; - -//! 用于调用python函数,生成tuple类型的python函数参数的工具类 -struct pycall_arg_t -{ - pycall_arg_t(int arg_num): - arg_index(0), - pargs_tuple(PyTuple_New(arg_num)) - {} - ~pycall_arg_t() - { - release(); - } - PyObject * get_args() const - { - return pargs_tuple; - } - template - pycall_arg_t& add(const T& val_) - { - if (arg_index < PyTuple_Size(pargs_tuple)) - { - PyObject* tmp_arg = pytype_traits_t::pyobj_from_cppobj(val_); - PyTuple_SetItem(pargs_tuple, arg_index, tmp_arg); - ++arg_index; - } - return *this; - } - void release() - { - if (pargs_tuple) - { - Py_DECREF(pargs_tuple); - pargs_tuple = NULL; - } - } - int arg_index; - PyObject * pargs_tuple; -}; - -//! 用于调用python函数,获取返回值的工具类 -class pytype_tool_t -{ -public: - virtual ~pytype_tool_t(){}; - virtual int parse_value(PyObject *pvalue_) = 0; - virtual const char* return_type() {return "";} - virtual bool need_release() { return false; } -}; - -//! 用于调用python函数,获取返回值的工具泛型类 -template -class pytype_tool_impl_t; -//! 封装调用python函数的C API -struct pycall_t -{ - static int call_func(PyObject *pModule, const std::string& mod_name_, const std::string& func_name_, - pycall_arg_t& pyarg_, pytype_tool_t& pyret_, std::string& err_) - { - PyObject *pFunc = PyObject_GetAttrString(pModule, func_name_.c_str()); - if (pFunc && PyCallable_Check(pFunc)) { - PyObject *pArgs = pyarg_.get_args(); - PyObject *pValue = PyObject_CallObject(pFunc, pArgs); - pyarg_.release();//! 等价于Py_DECREF(pArgs); - - if (pValue != NULL) { - if (pyret_.parse_value(pValue)) - { - err_ += "value returned is not "; - err_ += pyret_.return_type(); - err_ += std::string(" ") + func_name_ + " in " + mod_name_; - } - if (pyret_.need_release()){ - Py_DECREF(pValue); - } - } - } - else - { - err_ += "Cannot find function "; - err_ += func_name_ + " in " + mod_name_ + ","; - } - - Py_XDECREF(pFunc); - if (PyErr_Occurred()) - { - pyops_t::traceback(err_); - return 0; - } - return 0; - } - static int call_func_obj(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_t& pyret_, std::string& err_) - { - if (pFunc && PyCallable_Check(pFunc)) { - PyObject *pArgs = pyarg_.get_args(); - PyObject *pValue = PyObject_CallObject(pFunc, pArgs); - pyarg_.release();//! 等价于Py_DECREF(pArgs); - - if (pValue != NULL) { - if (pyret_.parse_value(pValue)) - { - err_ += "value returned is not "; - err_ += pyret_.return_type(); - } - if (pyret_.need_release()){ - Py_DECREF(pValue); - } - } - } - else - { - err_ += "invalid function"; - } - - if (PyErr_Occurred()) - { - pyops_t::traceback(err_); - return 0; - } - return 0; - } - template - static const T& call(const std::string& mod_name_, const std::string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); - template - static const T& call_obj_method(PyObject *pObj, const std::string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); - template - static const T& call_lambda(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret); -}; -//! 用于扩展python的工具类,用来解析参数 -struct pyext_tool_t; - - -template -struct pyext_return_tool_t; - -//! 用于扩展python,生成pyobject类型的返回值给python -template -struct pyext_func_traits_t; - -//! 用于扩展python,traits出注册给python的函数接口 -#ifndef PYCTOR -#define PYCTOR int (*) -#endif -//! 表示void类型,由于void类型不能return,用void_ignore_t适配 -template -struct void_ignore_t; - -template -struct void_ignore_t -{ - typedef T value_t; -}; - -template<> -struct void_ignore_t -{ - typedef cpp_void_t value_t; -}; - -#define RET_V typename void_ignore_t::value_t - -//! 记录各个基类和子类的相互关系 -struct cpp_to_pyclass_reg_info_t -{ - struct inherit_info_t - { - inherit_info_t():pytype_def(NULL){} - PyTypeObject* pytype_def; - std::string inherit_name; - std::set all_child; - }; - typedef std::map inherit_info_map_t; - static inherit_info_map_t& get_all_info() - { - static inherit_info_map_t inherit_info; - return inherit_info; - } - - static void add(const std::string& child_, const std::string& base_, PyTypeObject* def_) - { - inherit_info_t tmp; - tmp.inherit_name = base_; - tmp.pytype_def = def_; - get_all_info()[child_] = tmp; - get_all_info()[base_].all_child.insert(def_); - } - static bool is_instance(PyObject* pysrc, const std::string& class_) - { - inherit_info_map_t& inherit_info = get_all_info(); - inherit_info_t& tmp = inherit_info[class_]; - if (tmp.pytype_def && PyObject_TypeCheck(pysrc, tmp.pytype_def)) - { - return true; - } - for (std::set::iterator it = tmp.all_child.begin(); it != tmp.all_child.end(); ++it) - { - if (*it && PyObject_TypeCheck(pysrc, *it)) - { - return true; - } - } - - return false; - } - -}; - - -//! 记录C++ class 对应到python中的名称、参数信息等,全局 -struct static_pytype_info_t -{ - std::string class_name; - std::string mod_name; - int total_args_num; - PyTypeObject* pytype_def; -}; - -//! 工具类,用于生成分配python class的接口,包括分配、释放 -template -struct pyclass_base_info_t -{ - struct obj_data_t - { - obj_data_t():obj(NULL){} - - PyObject_HEAD - T* obj; - bool forbid_release; - void disable_auto_release(){ forbid_release = true; } - void release() - { - if (obj) - { - delete obj; - obj = NULL; - } - } - }; - - static void free_obj(obj_data_t* self) - { - if (false == self->forbid_release && self->obj) - { - self->release(); - } - self->ob_base.ob_type->tp_free((PyObject*)self); - } - - static PyObject *alloc_obj(PyTypeObject *type, PyObject *args, PyObject *kwds) - { - obj_data_t *self = (obj_data_t *)type->tp_alloc(type, 0); - return (PyObject *)self; - } - static PyObject *release(PyTypeObject *type, PyObject *args) - { - obj_data_t *self = (obj_data_t *)type; - self->release(); - return Py_BuildValue("i", 1); - } - static static_pytype_info_t pytype_info; -}; -template -static_pytype_info_t pyclass_base_info_t::pytype_info; - -//! 方便生成pyclass 初始化函数 -template -struct pyclass_ctor_tool_t; - -//! used to gen method of py class -template -struct pyclass_method_gen_t; - -//! 防止出现指针为NULL调用出错 -#define NULL_PTR_GUARD(X) if (NULL == X) {PyErr_SetString(PyExc_TypeError, "obj data ptr NULL");return NULL;} - -//! 用于生成python 的getter和setter接口,适配于c++ class的成员变量 -template -struct pyclass_member_func_gen_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - typedef RET CLASS_TYPE::* property_ptr_t; - - static PyObject *getter_func(obj_data_t *self, void *closure) - { - property_ptr_t property_ptr; - ::memcpy((void*)&property_ptr, (const void*)&closure, sizeof(closure)); - NULL_PTR_GUARD(self->obj); - CLASS_TYPE* p = self->obj; - return pytype_traits_t::pyobj_from_cppobj(p->*property_ptr); - } - static int setter_func(obj_data_t *self, PyObject *value, void *closure) - { - property_ptr_t property_ptr; - ::memcpy((void*)&property_ptr, (const void*)&closure, sizeof(closure)); - CLASS_TYPE* p = self->obj; - - return pytype_traits_t::pyobj_to_cppobj(value, p->*property_ptr); - } -}; - -//! 用于C++ 注册class的工具类,会记录class对应的名称、成员方法、成员变量 -class pyclass_regigster_tool_t -{ -public: - struct method_info_t - { - PyCFunction func; - std::string func_name; - std::string func_real_name; - std::string doc; - std::string doc_real; - int args_num; - int option_args_num; - PTR_NUMBER func_addr; - }; - struct property_info_t - { - void* ptr; - std::string property_name; - std::string doc; - getter getter_func; - setter setter_func; - }; - virtual ~pyclass_regigster_tool_t(){} - - typedef PyObject *(*pyobj_alloc_t)(PyTypeObject*, PyObject*, PyObject*); - - std::string class_name; - std::string class_real_name; - std::string class_name_with_mod; - std::string class_reel_name_with_mod; - std::string inherit_name; - int type_size; - std::string doc; - int args_num; - int option_args_num; - destructor dector; - initproc init; - pyobj_alloc_t ctor; - - //! member functions - PyCFunction delete_func; - std::vector methods_info; - //! property - std::vector propertys_info; - //! for init module - PyTypeObject pytype_def; - //! method - std::vector pymethod_def; - //! property - std::vector pyproperty_def; - - //! 静态类型需要全局记录该类型被注册成神马python 类型 - static_pytype_info_t* static_pytype_info; - - template - pyclass_regigster_tool_t& reg(FUNC f_, const std::string& func_name_, std::string doc_ = "") - { - method_info_t tmp; - tmp.func_name = func_name_; - tmp.func_real_name = func_name_ + "_internal_"; - tmp.doc = doc_; - tmp.doc_real = "internal use"; - tmp.func = (PyCFunction)pyclass_method_gen_t::pymethod; - tmp.args_num = pyclass_method_gen_t::args_num(); - tmp.option_args_num = pyclass_method_gen_t::option_args_num(); - ::memcpy((void*)&tmp.func_addr, (const void*)&f_, sizeof(void*)); - methods_info.push_back(tmp); - return *this; - } - template - pyclass_regigster_tool_t& reg_property(RET CLASS_TYPE::* member_, const std::string& member_name_, std::string doc_ = "") - { - property_info_t tmp; - ::memcpy((void*)&tmp.ptr, (const void*)&member_, sizeof(member_)); - tmp.property_name = member_name_; - tmp.doc = doc_; - tmp.getter_func = (getter)pyclass_member_func_gen_t::getter_func; - tmp.setter_func = (setter)pyclass_member_func_gen_t::setter_func; - propertys_info.push_back(tmp); - return *this; - } -}; - - -template -struct type_ref_traits_t -{ - typedef T value_t; - typedef T& ref_t; - value_t value; -}; -template -struct type_ref_traits_t -{ - typedef T value_t; - typedef T& ref_t; - value_t value; -}; -template -struct type_ref_traits_t -{ - typedef T value_t; - typedef T& ref_t; - value_t value; -}; -//! 用于判断是否是可选参数 -template -struct pyoption_traits_t -{ - static int is() { return 0;} -}; -template -struct pyoption_traits_t > -{ - static int is() { return 1;} -}; - - -template<>//typename T> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const long& val_) - { - return PyLong_FromLong(long(val_)); - } - static int pyobj_to_cppobj(PyObject *pvalue_, long& m_ret) - { - if (true == PyLong_Check(pvalue_)) - { - m_ret = (long)PyLong_AsLong(pvalue_); - return 0; - } - /*else if (true == PyInt_Check(pvalue_)) - { - m_ret = (long)PyInt_AsLong(pvalue_); - return 0; - }*/ - return -1; - } - static const char* get_typename() { return "long";} -}; - -#define IMPL_INT_CODE(X) \ -template<> \ -struct pytype_traits_t \ -{ \ - static PyObject* pyobj_from_cppobj(const X& val_) \ - { \ - return PyLong_FromLong(long(val_)); \ - } \ - static int pyobj_to_cppobj(PyObject *pvalue_, X& m_ret) \ - { \ - if (true == PyLong_Check(pvalue_)) \ - { \ - m_ret = (X)PyLong_AsLong(pvalue_); \ - return 0; \ - } \ - return -1; \ - } \ - static const char* get_typename() { return #X;} \ -}; - -IMPL_INT_CODE(int) -IMPL_INT_CODE(unsigned int) -IMPL_INT_CODE(short) -IMPL_INT_CODE(unsigned short) -IMPL_INT_CODE(char) -IMPL_INT_CODE(unsigned char) - -#ifdef _WIN32 -IMPL_INT_CODE(unsigned long) -IMPL_INT_CODE(int64_t) -#else -#ifndef __x86_64__ -IMPL_INT_CODE(int64_t) -#endif -IMPL_INT_CODE(uint64_t) -#endif - -template -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const T* val_) - { - const std::string& mod_name = pyclass_base_info_t::pytype_info.mod_name; - const std::string& class_name = pyclass_base_info_t::pytype_info.class_name; - PyObject *pName = NULL, *pModule = NULL, *pValue = NULL; - - if (class_name.empty()) - return pytype_traits_t::pyobj_from_cppobj(PTR_NUMBER(val_)); - - pName = PyString_FromString(mod_name.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - if (PyErr_Occurred()) - PyErr_Print(); - fprintf(stderr, "Failed to load \"%s\"\n", mod_name.c_str()); - assert(NULL && "this can not be happened"); - return NULL; - } - PyObject *pyclass = PyObject_GetAttrString(pModule, class_name.c_str()); - if (pyclass && PyCallable_Check(pyclass)) { - PyObject *pArgs = PyTuple_New(pyclass_base_info_t::pytype_info.total_args_num+1); - for (int i = 0; i< pyclass_base_info_t::pytype_info.total_args_num; ++i) - { - PyTuple_SetItem(pArgs, i, pytype_traits_t::pyobj_from_cppobj(0)); - } - - PyObject *palloc = pyclass_base_info_t::alloc_obj(pyclass_base_info_t::pytype_info.pytype_def, NULL, NULL); - typename pyclass_base_info_t::obj_data_t* pdest_obj = (typename pyclass_base_info_t::obj_data_t*)palloc; - //pdest_obj->obj = val_; - ::memcpy((void*)&pdest_obj->obj, (const void*)&val_, sizeof(pdest_obj->obj)); - pdest_obj->disable_auto_release(); - PyTuple_SetItem(pArgs, pyclass_base_info_t::pytype_info.total_args_num, palloc); - pValue = PyObject_CallObject(pyclass, pArgs); - Py_XDECREF(pArgs); - } - - Py_XDECREF(pyclass); - Py_DECREF(pModule); - return pValue; - } - - static int pyobj_to_cppobj(PyObject *pvalue_, T*& m_ret) - { - PyObject *pysrc = PyObject_GetAttrString(pvalue_, "obj"); - //!PyObject_TypeCheck(pysrc, pyclass_base_info_t::pytype_info.pytype_def)) { - if (NULL == pysrc || false == cpp_to_pyclass_reg_info_t::is_instance(pysrc, pyclass_base_info_t::pytype_info.class_name)) - { - Py_XDECREF(pysrc); - return -1; - } - typename pyclass_base_info_t::obj_data_t* pdest_obj = (typename pyclass_base_info_t::obj_data_t*)pysrc; - - m_ret = pdest_obj->obj; - Py_XDECREF(pysrc); - return 0; - } - - static const char* get_typename() { return pyclass_base_info_t::pytype_info.class_name.c_str();} -}; - -template -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(T* val_) - { - return pytype_traits_t::pyobj_from_cppobj(val_); - } - static int pyobj_to_cppobj(PyObject *pvalue_,T*& m_ret) - { - return pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret); - } - static const char* get_typename() { return pyclass_base_info_t::pytype_info.class_name.c_str();} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(PyObject* val_) - { - return val_; - } - static int pyobj_to_cppobj(PyObject *pvalue_, PyObject*& m_ret) - { - m_ret = pvalue_; - return 0; - } - static const char* get_typename() { return "PyObject";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const char* const val_) - { - return PyString_FromString(val_); - } - /* - static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) - { - if (true == PyString_Check(pvalue_)) - { - m_ret = PyString_AsString(pvalue_); - return 0; - } - return -1; - } - */ - static const char* get_typename() { return "std::string";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const char*& val_) - { - return PyString_FromString(val_); - } - /* - static int pyobj_to_cppobj(PyObject *pvalue_, char*& m_ret) - { - if (true == PyString_Check(pvalue_)) - { - m_ret = PyString_AsString(pvalue_); - return 0; - } - return -1; - } - */ - static const char* get_typename() { return "std::string";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(bool val_) - { - if (val_) - { - Py_RETURN_TRUE; - } - Py_RETURN_FALSE; - } - static int pyobj_to_cppobj(PyObject *pvalue_, bool& m_ret) - { - if (Py_False == pvalue_|| Py_None == pvalue_) - { - m_ret = false; - } - else - { - m_ret = true; - } - return 0; - } - static const char* get_typename() { return "bool";} -}; - -template -struct pytype_traits_t > -{ - static int pyobj_to_cppobj(PyObject *pvalue_, pyoption_t& m_ret) - { - if (Py_None == pvalue_) - { - return 0; - } - else if (0 == pytype_traits_t::value_t>::pyobj_to_cppobj(pvalue_, m_ret.value())) - { - m_ret.std::set(); - return 0; - } - return -1; - } - static const char* get_typename() { return "pyoption_t";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(const std::string& val_) - { - return PyString_FromStringAndSize(val_.c_str(), val_.size()); - } - static int pyobj_to_cppobj(PyObject *pvalue_, std::string& m_ret) - { - if (true == PyString_Check(pvalue_)) - { - const char* pDest = NULL; - Py_ssize_t nLen = 0; - PyString_AsStringAndSize(pvalue_, &pDest, &nLen); - - m_ret.assign(pDest, nLen); - return 0; - } - else if (true == PyUnicode_Check(pvalue_)) - { - const char* pDest = NULL; - Py_ssize_t nLen = 0; - PyString_AsStringAndSize(pvalue_, &pDest, &nLen); - m_ret.assign(pDest, nLen); - return 0; - /* -#ifdef _WIN32 - PyObject* retStr = PyUnicode_AsEncodedString(pvalue_, "gbk", ""); -#else - PyObject* retStr = PyUnicode_AsUTF8String(pvalue_); -#endif - if (retStr) - { - m_ret = PyString_AsString(retStr); - Py_XDECREF(retStr); - return 0; - } - */ - } - return -1; - } - static const char* get_typename() { return "std::string";} -}; - -//#ifdef _WIN32 -//template<> -//struct pytype_traits_t -//{ -// static PyObject* pyobj_from_cppobj(const wstring& wstr) -// { -// return PyUnicode_FromWideChar(wstr.c_str(), wstr.length()); -// } -// static int pyobj_to_cppobj(PyObject *pvalue_, wstring& wstr_ret) -// { -// if (true == PyString_Check(pvalue_)) -// { -// PyObject* retStr = PyUnicode_FromObject(pvalue_); -// if (retStr) -// { -// int n = PyUnicode_GetSize(retStr); -// wstr_ret.resize(n); -// n = PyUnicode_AsWideChar((PyUnicodeObject*)retStr, &(wstr_ret[0]), n); -// Py_XDECREF(retStr); -// return 0; -// } -// return 0; -// } -// else if (true == PyUnicode_Check(pvalue_)) -// { -// int n = PyUnicode_GetSize(pvalue_); -// wstr_ret.resize(n); -// n = PyUnicode_AsWideChar((PyUnicodeObject*)pvalue_, &(wstr_ret[0]), n); -// return 0; -// } -// return -1; -// } -// static const char* get_typename() { return "wstring";} -//}; -//#endif - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(float val_) - { - return PyFloat_FromDouble(double(val_)); - } - static int pyobj_to_cppobj(PyObject *pvalue_, float& m_ret) - { - if (true == PyFloat_Check(pvalue_)) - { - m_ret = (float)PyFloat_AsDouble(pvalue_); - return 0; - } - return -1; - } - static const char* get_typename() { return "float";} -}; - -template<> -struct pytype_traits_t -{ - static PyObject* pyobj_from_cppobj(double val_) - { - return PyFloat_FromDouble(val_); - } - static int pyobj_to_cppobj(PyObject *pvalue_, double& m_ret) - { - if (true == PyFloat_Check(pvalue_)) - { - m_ret = PyFloat_AsDouble(pvalue_); - return 0; - } - return -1; - } - static const char* get_typename() { return "double";} -}; - -template -struct pytype_traits_t > -{ - static PyObject* pyobj_from_cppobj(const std::vector& val_) - { - PyObject* ret = PyList_New(val_.size()); - for (size_t i = 0; i < val_.size(); ++i) - { - PyList_SetItem(ret, i, pytype_traits_t::pyobj_from_cppobj(val_[i])); - } - return ret; - } - static int pyobj_to_cppobj(PyObject *pvalue_, std::vector& m_ret) - { - m_ret.clear(); - if (true == PyTuple_Check(pvalue_)) - { - int64_t n = PyTuple_Size(pvalue_); - for (int64_t i = 0; i < n; ++i) - { - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyTuple_GetItem(pvalue_, i))) - { - return -1; - } - m_ret.push_back(ret_tool.get_value()); - } - return 0; - } - else if (true == PyList_Check(pvalue_)) - { - int64_t n = PyList_Size(pvalue_); - for (int64_t i = 0; i < n; ++i) - { - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyList_GetItem(pvalue_, i))) - { - return -1; - } - m_ret.push_back(ret_tool.get_value()); - } - return 0; - } - return -1; - } - static const char* get_typename() { return "std::vector";} -}; -template -struct pytype_traits_t > -{ - static PyObject* pyobj_from_cppobj(const std::list& val_) - { - size_t n = val_.size(); - PyObject* ret = PyList_New(n); - int i = 0; - for (typename std::list::const_iterator it = val_.begin(); it != val_.end(); ++it) - { - PyList_SetItem(ret, i++, pytype_traits_t::pyobj_from_cppobj(*it)); - } - return ret; - } - static int pyobj_to_cppobj(PyObject *pvalue_, std::list& m_ret) - { - pytype_tool_impl_t ret_tool; - if (true == PyTuple_Check(pvalue_)) - { - int64_t n = PyTuple_Size(pvalue_); - for (int64_t i = 0; i < n; ++i) - { - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyTuple_GetItem(pvalue_, i))) - { - return -1; - } - m_ret.push_back(ret_tool.get_value()); - } - return 0; - } - else if (true == PyList_Check(pvalue_)) - { - int64_t n = PyList_Size(pvalue_); - for (int64_t i = 0; i < n; ++i) - { - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyList_GetItem(pvalue_, i))) - { - return -1; - } - m_ret.push_back(ret_tool.get_value()); - } - return 0; - } - return -1; - } - static const char* get_typename() { return "std::list";} -}; -template -struct pytype_traits_t > -{ - static PyObject* pyobj_from_cppobj(const std::set& val_) - { - PyObject* ret = PySet_New(NULL); - for (typename std::set::const_iterator it = val_.begin(); it != val_.end(); ++it) - { - PyObject *v = pytype_traits_t::pyobj_from_cppobj(*it); - PySet_Add(ret, v); - Py_DECREF(v); - } - return ret; - } - static int pyobj_to_cppobj(PyObject *pvalue_, std::set& m_ret) - { - m_ret.clear(); - pytype_tool_impl_t ret_tool; - PyObject *iter = PyObject_GetIter(pvalue_); - PyObject *item = NULL; - while (NULL != iter && NULL != (item = PyIter_Next(iter))) - { - T tmp(); - if (pytype_traits_t::pyobj_to_cppobj(item, tmp)) - { - Py_DECREF(item); - Py_DECREF(iter); - return -1; - } - m_ret.insert(tmp); - Py_DECREF(item); - } - if (iter) - { - Py_DECREF(iter); - return 0; - } - return -1; - } - static const char* get_typename() { return "std::set";} -}; -template -struct pytype_traits_t > -{ - static PyObject* pyobj_from_cppobj(const std::map& val_) - { - PyObject* ret = PyDict_New(); - for (typename std::map::const_iterator it = val_.begin(); it != val_.end(); ++it) - { - PyObject *k = pytype_traits_t::pyobj_from_cppobj(it->first); - PyObject *v = pytype_traits_t::pyobj_from_cppobj(it->second); - PyDict_SetItem(ret, k, v); - Py_DECREF(k); - Py_DECREF(v); - } - return ret; - } - static int pyobj_to_cppobj(PyObject *pvalue_, std::map& m_ret) - { - m_ret.clear(); - pytype_tool_impl_t ret_tool_T; - pytype_tool_impl_t ret_tool_R; - if (true == PyDict_Check(pvalue_)) - { - PyObject *key = NULL, *value = NULL; - Py_ssize_t pos = 0; - - while (PyDict_Next(pvalue_, &pos, &key, &value)) - { - T tmp_key; - R tmp_value; - if (pytype_traits_t::pyobj_to_cppobj(key, tmp_key) || - pytype_traits_t::pyobj_to_cppobj(value, tmp_value)) - { - return -1; - } - m_ret[tmp_key] = tmp_value; - } - return 0; - } - return -1; - } - static const char* get_typename() { return "std::map";} -}; - - -template -class pytype_tool_impl_t: public pytype_tool_t -{ -public: - pytype_tool_impl_t():m_ret(){} - - virtual int parse_value(PyObject *pvalue_) - { - if (pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret)) - { - return -1; - } - return 0; - } - - const T& get_value() const { return m_ret; } - virtual const char* return_type() {return pytype_traits_t::get_typename();} -private: - T m_ret; -}; - -template<> -class pytype_tool_impl_t: public pytype_tool_t -{ -public: - pytype_tool_impl_t():m_ret(){} - - virtual int parse_value(PyObject *pvalue_) - { - return 0; - } - - const cpp_void_t& get_value() const { return m_ret; } - virtual const char* return_type() { return "void";} -private: - cpp_void_t m_ret; -}; -template -class pytype_tool_impl_t: public pytype_tool_t -{ -public: - pytype_tool_impl_t():m_ret(){} - - virtual int parse_value(PyObject *pvalue_) - { - if (pytype_traits_t::pyobj_to_cppobj(pvalue_, m_ret)) - { - return -1; - } - return 0; - } - - T* get_value() const { return m_ret; } -private: - T* m_ret; -}; - - -template<> -class pytype_tool_impl_t: public pytype_tool_t -{ -public: - pytype_tool_impl_t():m_ret(){} - - virtual int parse_value(PyObject *pvalue_) - { - m_ret = pvalue_; - return 0; - } - - PyObject*& get_value() { return m_ret; } - bool need_release() { return false; } -private: - PyObject* m_ret; -}; - -#endif diff --git a/pyops_for_embed.h b/pyops_for_embed.h deleted file mode 100644 index 6b8857a..0000000 --- a/pyops_for_embed.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef __PYOPS_FOR_EMBED -#define __PYOPS_FOR_EMBED - -#include "pyops_base.h" - - - - - -template -const T& pycall_t::call(const std::string& mod_name_, const std::string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) -{ - PyObject *pName = NULL, *pModule = NULL; - std::string err_msg; - - pName = PyString_FromString(mod_name_.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - pyops_t::traceback(err_msg); - throw std::runtime_error(err_msg.c_str()); - return pyret.get_value(); - } - - call_func(pModule, mod_name_, func_name_, pyarg_, pyret, err_msg); - Py_DECREF(pModule); - - if (!err_msg.empty()) - { - throw std::runtime_error(err_msg.c_str()); - } - return pyret.get_value(); -} -template -const T& pycall_t::call_obj_method(PyObject *pObj, const std::string& func_name_, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) -{ - std::string err_msg; - if (NULL == pObj) - { - pyops_t::traceback(err_msg); - throw std::runtime_error(err_msg.c_str()); - return pyret.get_value(); - } - - static std::string mod_name_ = "NaN"; - call_func(pObj, mod_name_, func_name_, pyarg_, pyret, err_msg); - - if (!err_msg.empty()) - { - throw std::runtime_error(err_msg.c_str()); - } - return pyret.get_value(); -} - -template -const T& pycall_t::call_lambda(PyObject *pFunc, pycall_arg_t& pyarg_, pytype_tool_impl_t& pyret) -{ - std::string err_msg; - if (NULL == pFunc) - { - err_msg = "can not call null PyObject"; - throw std::runtime_error(err_msg.c_str()); - return pyret.get_value(); - } - - call_func_obj(pFunc, pyarg_, pyret, err_msg); - - if (!err_msg.empty()) - { - throw std::runtime_error(err_msg.c_str()); - } - return pyret.get_value(); -} - - -#endif diff --git a/pyops_for_extend.h b/pyops_for_extend.h deleted file mode 100644 index 94aa693..0000000 --- a/pyops_for_extend.h +++ /dev/null @@ -1,1745 +0,0 @@ -#ifndef __PYOPS_FOR_EXTEND_ -#define __PYOPS_FOR_EXTEND_ - -#include "pyops_base.h" - - - -//! 用于扩展python的工具类,用来解析参数 -struct pyext_tool_t -{ - pyext_tool_t(PyObject* args_): - m_args(args_), - m_arg_tuple(NULL), - m_index(0), - m_err(false), - m_func_addr(0) - { - if (!PyArg_ParseTuple(args_, "LO", &m_func_addr, &m_arg_tuple)) { - m_err = true; - return; - } - if (NULL == m_arg_tuple || false == PyTuple_Check(m_arg_tuple)) - { - PyErr_SetString(PyExc_TypeError, "arg type invalid(shoule func_name, args tuple)"); - m_err = true; - return; - } - m_size = PyTuple_Size(m_arg_tuple); - } - - template - pyext_tool_t& parse_arg(T& ret_arg_) - { - typedef typename type_ref_traits_t::value_t value_t; - if (false == m_err) - { - if (m_index >= m_size) - { - std::stringstream ss; - ss << "param num invalid, only["<< m_index + 1 <<"] provided"; - PyErr_SetString(PyExc_TypeError, ss.str().c_str()); - m_err = true; - return *this; - } - - pytype_tool_impl_t ret_tool; - if (ret_tool.parse_value(PyTuple_GetItem(m_arg_tuple, m_index))) - { - std::stringstream ss; - ss << "param[" << m_index + 1 << "] type invalid, "<< pytype_traits_t::get_typename() << " needed"; - PyErr_SetString(PyExc_TypeError, ss.str().c_str()); - m_err = true; - return *this; - } - ++m_index; - ret_arg_ = ret_tool.get_value(); - } - return *this; - } - - bool is_err() const { return m_err;} - PTR_NUMBER get_func_addr() const { return m_func_addr;} - - template - FUNC get_func_ptr() const - { - FUNC f = NULL; - ::memcpy((void*)&f, (const void*)&m_func_addr, sizeof(m_func_addr)); - return f; - } - PyObject* m_args; - PyObject* m_arg_tuple; - int m_index; - int64_t m_size; - bool m_err;//! 是否异常 - int64_t m_func_addr; -}; - - - -//! 用于扩展python,生成pyobject类型的返回值给python -template -struct pyext_return_tool_t -{ - //! 用于静态方法 - template - static PyObject* route_call(F f) - { - return pytype_traits_t::pyobj_from_cppobj(f()); - } - template - static PyObject* route_call(F f, ARG1& a1) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value, a8.value)); - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) - { - return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value, a8.value, a9.value)); - } - //! 用于成员方法 - template - static PyObject* route_method_call(O o, F f) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)()); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value, a8.value)); - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) - { - NULL_PTR_GUARD(o); - return pytype_traits_t::pyobj_from_cppobj((o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, - a7.value, a8.value, a9.value)); - } -}; - - -template<> -struct pyext_return_tool_t -{ - template - static PyObject* route_call(F f) - { - f(); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1) - { - f(a1.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2) - { - f(a1.value, a2.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3) - { - f(a1.value, a2.value, a3.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) - { - f(a1.value, a2.value, a3.value, a4.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); - Py_RETURN_NONE; - } - template - static PyObject* route_call(F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) - { - f(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f) - { - (o->*f)(); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1) - { - (o->*f)(a1.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2) - { - (o->*f)(a1.value, a2.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3) - { - (o->*f)(a1.value, a2.value, a3.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); - Py_RETURN_NONE; - } - template - static PyObject* route_method_call(O o, F f, ARG1& a1, ARG2& a2, ARG3& a3, ARG4& a4, ARG5& a5, ARG6& a6, ARG7& a7, ARG8& a8, ARG9& a9) - { - (o->*f)(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); - Py_RETURN_NONE; - } -}; - - - -//! 用于扩展python,traits出注册给python的函数接口 -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(); - static int args_num() { return 0;} - static int option_args_num() { return 0;} - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - return pyext_return_tool_t::route_call(f); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1); - static int args_num(){ return 1-option_args_num();} - static int option_args_num() - { - return pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - if (pyext_tool.parse_arg(a1.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2); - static int args_num() { return 2 - option_args_num();} - static int option_args_num() - { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3); - static int args_num() { return 3-option_args_num();} - static int option_args_num() - { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3); - } -}; -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4); - static int args_num() { return 4-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5); - static int args_num() { return 5-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); - static int args_num() { return 6-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); - static int args_num() { return 7-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); - static int args_num() { return 8-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7, a8); - } -}; - -template -struct pyext_func_traits_t -{ - typedef RET (*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); - static int args_num() { return 9-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is() + - pyoption_traits_t::value_t>::is(); - } - static PyObject* pyfunc(PyObject* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = (func_t)pyext_tool.get_func_addr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - type_ref_traits_t a9; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_call(f, a1, a2, a3, a4, a5, a6, a7, a8, a9); - } -}; - - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - - self->obj = new CLASS_TYPE(); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - if (pyext_tool.parse_arg(a1.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value); - return 0; - } -}; - -template -struct pyclass_ctor_tool_t -{ - typedef typename pyclass_base_info_t::obj_data_t obj_data_t; - static int init_obj(obj_data_t *self, PyObject *args, PyObject *kwds) - { - if (self->obj) return 0; - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return -1; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - type_ref_traits_t a9; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) - { - return -1; - } - self->obj = new CLASS_TYPE(a1.value, a2.value, a3.value, a4.value, a5.value, a6.value, a7.value, a8.value, a9.value); - return 0; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(); - static int args_num() { return 0;} - static int option_args_num() { return 0;} - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1); - static int args_num() { return 1-option_args_num();} - static int option_args_num() { return pyoption_traits_t::value_t>::is();} - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - if (pyext_tool.parse_arg(a1.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2); - static int args_num() { return 2-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2);; - } -}; - - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3); - static int args_num() { return 3-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4); - static int args_num() { return 4-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5); - static int args_num() { return 5-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); - static int args_num() { return 6-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); - static int args_num() { return 7-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); - static int args_num() { return 8-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8);; - } -}; - - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); - static int args_num() { return 9-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - type_ref_traits_t a9; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8, a9);; - } -}; - -//! const类型成员函数--------------------------------------------------------------------------------------------- - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)() const; - static int args_num() { return 0;} - static int option_args_num() { return 0;} - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1) const; - static int args_num() { return 1-option_args_num();} - static int option_args_num() { return pyoption_traits_t::value_t>::is();} - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - if (pyext_tool.parse_arg(a1.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2) const; - static int args_num() { return 2-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2);; - } -}; - - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3) const; - static int args_num() { return 3-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4) const; - static int args_num() { return 4-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5) const; - static int args_num() { return 5-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) const; - static int args_num() { return 6-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) const; - static int args_num() { return 7-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7);; - } -}; - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8) const; - static int args_num() { return 8-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8);; - } -}; - - -template -struct pyclass_method_gen_t -{ - typedef RET (CLASS_TYPE::*func_t)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9) const; - static int args_num() { return 9-option_args_num();} - static int option_args_num() { - return pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is()+ - pyoption_traits_t::value_t>::is(); - } - - static PyObject *pymethod(typename pyclass_base_info_t::obj_data_t* self, PyObject* args) - { - pyext_tool_t pyext_tool(args); - if (pyext_tool.is_err()) - { - return NULL; - } - func_t f = pyext_tool.get_func_ptr(); - if (0 == f) - { - PyErr_SetString(PyExc_TypeError, "func address must provided"); - return NULL; - } - type_ref_traits_t a1; - type_ref_traits_t a2; - type_ref_traits_t a3; - type_ref_traits_t a4; - type_ref_traits_t a5; - type_ref_traits_t a6; - type_ref_traits_t a7; - type_ref_traits_t a8; - type_ref_traits_t a9; - if (pyext_tool.parse_arg(a1.value).parse_arg(a2.value).parse_arg(a3.value).parse_arg(a4.value) - .parse_arg(a5.value).parse_arg(a6.value).parse_arg(a7.value).parse_arg(a8.value).parse_arg(a9.value).is_err()) - { - return NULL; - } - return pyext_return_tool_t::route_method_call(self->obj, f, a1, a2, a3, a4, a5, a6, a7, a8, a9);; - } -}; - - -#endif From 7abcddb0887ba34256ba3811b581636e854a6625 Mon Sep 17 00:00:00 2001 From: fanchy Date: Wed, 17 Jun 2020 20:59:35 +0800 Subject: [PATCH 11/13] add new version ffpython --- example.cpp | 144 ++-- ffpython.cpp | 994 +++++++++------------- ffpython.h | 2265 +++++++++++++++++++++++++++++++++++++++----------- fftest.py | 160 ++-- gencode.py | 221 +++++ 5 files changed, 2532 insertions(+), 1252 deletions(-) create mode 100644 gencode.py diff --git a/example.cpp b/example.cpp index 2c5bb15..bf6ce6d 100644 --- a/example.cpp +++ b/example.cpp @@ -7,80 +7,81 @@ #define TestGuard(X, Y) printf("-------%s begin-----------\n", X);try {Y;}catch(std::exception& e_){printf("exception<%s>\n", e_.what());}\ printf("-------%s end-----------\n", X); +using namespace ff; -void test_base(ffpython_t& ffpython) +void testBase(FFPython& ffpython) { - printf("sys.version=%s\n", ffpython.get_global_var("sys", "version").c_str()); - ffpython.set_global_var("fftest", "global_var", "OhNice"); - printf("fftest.global_var=%s\n", ffpython.get_global_var("fftest", "global_var").c_str()); + printf("sys.version=%s\n", ffpython.getVar("sys", "version").c_str()); + ffpython.setVar("fftest", "global_var", "OhNice"); + printf("fftest.global_var=%s\n", ffpython.getVar("fftest", "global_var").c_str()); printf("os.getcwd=%s\n", ffpython.call("os", "getcwd").c_str()); printf("time.asctime=%s\n", ffpython.call("time", "asctime").c_str()); int a1 = 100; float a2 = 3.14f; std::string a3 = "OhWell"; - ffpython.call("fftest", "test_base", a1, a2, a3); + ffpython.call("fftest", "testBase", a1, a2, a3); } -void test_stl(ffpython_t& ffpython) +void testStl(FFPython& ffpython) { std::vector a1;a1.push_back(100);a1.push_back(200); std::list a2; a2.push_back("Oh");a2.push_back("Nice"); std::vector > a3;a3.push_back(a2); - ffpython.call("fftest", "test_stl", a1, a2, a3); + ffpython.call("fftest", "testStl", a1, a2, a3); } -void test_return_stl(ffpython_t& ffpython) +void test_returnStl(FFPython& ffpython) { - typedef std::map > > ret_t; - ret_t val = ffpython.call("fftest", "test_return_stl"); + //typedef std::map > > ret_t; + //ret_t val = ffpython.call("fftest", "test_returnStl"); } -static int print_val(int a1, float a2, const std::string& a3, const std::vector& a4) +static int printVal(int a1, float a2, const std::string& a3, const std::vector& a4) { printf("%s[%d,%g,%s,%d]\n", __FUNCTION__, a1, a2, a3.c_str(), (int)a4.size()); return 0; } -struct ops_t +struct OpsTest { - static std::list return_stl() + static std::list returnStl() { std::list ret;ret.push_back(1024); printf("%s\n", __FUNCTION__); return ret; } }; -void test_register_base_class(ffpython_t& ffpython) +void testRegisterBaseClass(FFPython& ffpython) { - ffpython.call("fftest", "test_register_base_class"); + ffpython.call("fftest", "testRegisterBaseClass"); }; -class foo_t +class Foo { public: - foo_t(int v_) :m_value(v_) + Foo(int v_) :nValue(v_) { printf("%s\n", __FUNCTION__); } - virtual ~foo_t() + virtual ~Foo() { printf("%s\n", __FUNCTION__); } - int get_value() const { return m_value; } - void set_value(int v_) { m_value = v_; } - void test_stl(std::map >& v_) + int getValue() { return nValue; } + void setValue(int v_) { nValue = v_; } + void testStl(std::map >& v_) { printf("%s\n", __FUNCTION__); } - int m_value; + int nValue; }; -class dumy_t : public foo_t +class Dumy : public Foo { public: - dumy_t(int v_) :foo_t(v_) + Dumy(int v_) :Foo(v_) { printf("%s\n", __FUNCTION__); } - ~dumy_t() + ~Dumy() { printf("%s\n", __FUNCTION__); } @@ -91,93 +92,90 @@ class dumy_t : public foo_t }; -static foo_t* obj_test(dumy_t* p) +static Foo* objTest(Dumy* p) { printf("%s\n", __FUNCTION__); return p; } -std::string test_reg_function(ffpython_t& ffpython) +std::string testRegFunction(FFPython& ffpython) { - ffpython.reg(&print_val, "print_val") - .reg(&ops_t::return_stl, "return_stl"); + ffpython.regFunc(&printVal, "printVal") + .regFunc(&OpsTest::returnStl, "returnStl"); - ffpython.reg_class("foo_t") - .reg(&foo_t::get_value, "get_value") - .reg(&foo_t::set_value, "set_value") - .reg(&foo_t::test_stl, "test_stl") - .reg_property(&foo_t::m_value, "m_value"); + ffpython.regClass("Foo") + .regMethod(&Foo::getValue, "getValue") + .regMethod(&Foo::setValue, "setValue") + .regMethod(&Foo::testStl, "testStl") + .regField(&Foo::nValue, "nValue"); - ffpython.reg_class("dumy_t", "dumy_t class inherit foo_t ctor ", "foo_t") - .reg(&dumy_t::dump, "dump"); + ffpython.regClass("Dumy", "Foo") + .regMethod(&Dumy::dump, "dump"); - ffpython.reg(obj_test, "obj_test"); + ffpython.regFunc(objTest, "objTest"); return "cppext"; } -void test_register_inherit_class(ffpython_t& ffpython) +void testRegisterInheritClass(FFPython& ffpython) { - ffpython.call("fftest", "test_register_inherit_class"); + ffpython.call("fftest", "testRegisterInheritClass"); }; -void test_cpp_obj_to_py(ffpython_t& ffpython) +void testCppObjToPy(FFPython& ffpython) { - foo_t tmp_foo(2013); - std::vector vt; + Dumy tmp_foo(2013); + std::vector vt; vt.push_back(&tmp_foo); - ffpython.call("fftest", "test_cpp_obj_to_py", &tmp_foo); - printf("test_cpp_obj_to_py changed m_value=%d\n", tmp_foo.m_value); - ffpython.call("fftest", "test_cpp_obj_to_py_ext", vt); + ffpython.call("fftest", "testCppObjToPy", &tmp_foo); + printf("testCppObjToPy changed nValue=%d\n", tmp_foo.nValue); + ffpython.call("fftest", "testCppObjToPy2", vt); } -void test_cpp_obj_py_obj(ffpython_t& ffpython) -{ - dumy_t tmp_foo(2013); - - //foo_t* p = ffpython.call("fftest", "test_cpp_obj_py_obj", &tmp_foo); - //p = NULL; -} -void test_py_class_lambda(ffpython_t& ffpython) +void testPyClassLambda(FFPython& ffpython) { - PyObject* pobj = ffpython.call("fftest", "test_cpp_obj_return_py_obj"); - ffpython.obj_call(pobj, "sayHi", 1, std::string("soNice")); - - PyObject* pFunc= ffpython.call("fftest", "test_cpp_obj_return_py_lambda"); - ffpython.call_lambda(pFunc, 112233); - + PyObject* pFunc= ffpython.call("fftest", "testCppObjReturnPyLambda"); + std::vector args; + args.push_back(ScriptCppOps::scriptFromCpp(1066)); + ffpython.callFuncByObjRet(pFunc, args); Py_XDECREF(pFunc); - Py_XDECREF(pobj); + + PyObject* pobj = ffpython.call("fftest", "testCppObjReturnPyObj"); + Py_INCREF(pobj); + std::vector args1; + args1.push_back(ScriptCppOps::scriptFromCpp(1111)); + args1.push_back(ScriptCppOps::scriptFromCpp("soNice")); + ffpython.callMethodByObjRet(pobj, "sayHi", args1); + Py_XDECREF(pobj); + } int main(int argc, char* argv[]) { try { - ffpython_t ffpython(&test_reg_function); - ffpython_t::add_path("./"); - ffpython_t::add_path("../"); + FFPython ffpython; + testRegFunction(ffpython); + ffpython.addPath("./"); + ffpython.addPath("../"); - TestGuard("test_base", test_base(ffpython)); + TestGuard("testBase", testBase(ffpython)); - TestGuard("test_stl", test_stl(ffpython)); - ffpython.call("fftest", "test_reg_function"); + TestGuard("testStl", testStl(ffpython)); + ffpython.call("fftest", "testRegFunction"); - TestGuard("test_register_base_class", test_register_base_class(ffpython)); + TestGuard("testRegisterBaseClass", testRegisterBaseClass(ffpython)); - TestGuard("test_register_inherit_class", test_register_inherit_class(ffpython)); + TestGuard("testRegisterInheritClass", testRegisterInheritClass(ffpython)); - TestGuard("test_cpp_obj_to_py", test_cpp_obj_to_py(ffpython));return 0; - - TestGuard("test_cpp_obj_py_obj", test_cpp_obj_py_obj(ffpython)); + TestGuard("testCppObjToPy", testCppObjToPy(ffpython)); - TestGuard("test_py_class_lambda", test_py_class_lambda(ffpython)); + TestGuard("testPyClassLambda", testPyClassLambda(ffpython)); #ifdef _WIN32 system("pause"); #endif - Py_Finalize(); } catch(std::exception& e) { printf("exception<%s>\n", e.what()); diff --git a/ffpython.cpp b/ffpython.cpp index bfd3561..de72b1b 100644 --- a/ffpython.cpp +++ b/ffpython.cpp @@ -1,608 +1,386 @@ -#include "ffpython.h" - - -//! 获取python异常信息 - -int pyops_t::traceback(std::string& ret_) -{ - PyObject* err = PyErr_Occurred(); - - if (err != NULL) { - PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL; - PyObject *pyth_module = NULL, *pyth_func = NULL; - - PyErr_Fetch(&ptype, &pvalue, &ptraceback); - if (pvalue) - { - if (true == PyList_Check(pvalue)) - { - int64_t n = PyList_Size(pvalue); - for (int64_t i = 0; i < n; ++i) - { - PyObject *pystr = PyObject_Str(PyList_GetItem(pvalue, i)); - ret_ += PyString_AsString(pystr); - ret_ += "\n"; - Py_DECREF(pystr); - } - } - if (true == PyTuple_Check(pvalue)) - { - int64_t n = PyTuple_Size(pvalue); - for (int64_t i = 0; i < n; ++i) - { - PyObject* tmp_str = PyTuple_GetItem(pvalue, i); - if (true == PyTuple_Check(tmp_str)) - { - int64_t m = PyTuple_Size(tmp_str); - for (int64_t j = 0; j < m; ++j) - { - PyObject *pystr = PyObject_Str(PyTuple_GetItem(tmp_str, j)); - ret_ += PyString_AsString(pystr); - ret_ += ","; - Py_DECREF(pystr); - } - } - else - { - PyObject *pystr = PyObject_Str(tmp_str); - ret_ += PyString_AsString(pystr); - Py_DECREF(pystr); - } - ret_ += "\n"; - } - } - else - { - PyObject *pystr = PyObject_Str(pvalue); - if (pystr) - { - ret_ += PyString_AsString(pystr); - ret_ += "\n"; - Py_DECREF(pystr); - } - } - } - - /* See if we can get a full traceback */ - PyObject *module_name = PyString_FromString("traceback"); - pyth_module = PyImport_Import(module_name); - Py_DECREF(module_name); - - if (pyth_module && ptype && pvalue && ptraceback) - { - pyth_func = PyObject_GetAttrString(pyth_module, "format_exception"); - if (pyth_func && PyCallable_Check(pyth_func)) { - PyObject *pyth_val = PyObject_CallFunctionObjArgs(pyth_func, ptype, pvalue, ptraceback, NULL); - if (pyth_val && true == PyList_Check(pyth_val)) - { - int64_t n = PyList_Size(pyth_val); - for (int64_t i = 0; i < n; ++i) - { - PyObject* tmp_str = PyList_GetItem(pyth_val, i); - PyObject *pystr = PyObject_Str(tmp_str); - if (pystr) - { - ret_ += PyString_AsString(pystr); - - Py_DECREF(pystr); - } - ret_ += "\n"; - } - } - Py_XDECREF(pyth_val); - } - } - Py_XDECREF(pyth_func); - Py_XDECREF(pyth_module); - Py_XDECREF(ptype); - Py_XDECREF(pvalue); - Py_XDECREF(ptraceback); - PyErr_Clear(); - return 0; - } - - return -1; -} - -ffpython_t::ffpython_t(ModInitFunc func) -{ - if (func) { - std::string modName = func(*this); - init(modName); - } - if (!Py_IsInitialized()) - Py_Initialize(); - rename_method(); - rename_pyclass(); -} -ffpython_t::~ffpython_t() -{ - clear_cache_pyobject(); -} - - -int ffpython_t::init_py() -{ - Py_Initialize(); - return 0; -} -int ffpython_t::final_py() -{ - Py_Finalize(); - return 0; -} - -int ffpython_t::add_path(const std::string& path_) -{ - char buff[1024]; - SAFE_SPRINTF(buff, sizeof(buff), "import sys\nif '%s' not in sys.path:\n\tsys.path.append('%s')\n", path_.c_str(), path_.c_str()); - PyRun_SimpleString(buff); - return 0; -} - -int ffpython_t::run_string(const std::string& py_) -{ - PyRun_SimpleString(py_.c_str()); - return 0; -} - -int ffpython_t::reload(const std::string& py_name_) -{ - PyObject *pName = NULL, *pModule = NULL; - std::string err_msg; - - pName = PyString_FromString(py_name_.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - pyops_t::traceback(err_msg); - throw std::runtime_error(err_msg.c_str()); - return -1; - } - - PyObject *pNewMod = PyImport_ReloadModule(pModule); - Py_DECREF(pModule); - if (NULL == pNewMod) - { - pyops_t::traceback(err_msg); - throw std::runtime_error(err_msg.c_str()); - return -1; - } - Py_DECREF(pNewMod); - return 0; -} -int ffpython_t::load(const std::string& py_name_) -{ - PyObject *pName = NULL, *pModule = NULL; - std::string err_msg; - - pName = PyString_FromString(py_name_.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - pyops_t::traceback(err_msg); - throw std::runtime_error(err_msg.c_str()); - return -1; - } - - Py_DECREF(pModule); - return 0; -} - -int ffpython_t::init(const std::string& mod_name_, std::string doc_) -{ - m_mod_name = mod_name_; - m_mod_doc = doc_; - init_method(); - init_pyclass(); - - static std::vector* vtmp; - static std::vector* all_pyclass; - vtmp = &m_pymethod_defs; - all_pyclass = &m_all_pyclass; - static PyModuleDef EmbModule = { - PyModuleDef_HEAD_INIT, m_mod_name.c_str(), NULL, -1, &((*vtmp)[0]), - NULL, NULL, NULL, NULL - }; - struct TmpLambda { - static PyObject* PyInit_emb(void) - { - PyObject* retObj = PyModule_Create(&EmbModule); - - for (size_t i = 0; i < (*all_pyclass).size(); ++i) - { - if (PyType_Ready(&((*all_pyclass)[i].pytype_def)) < 0) - return retObj; - PyObject* tmpP = (PyObject*)(&((*all_pyclass)[i].pytype_def)); - Py_INCREF(tmpP); - PyModule_AddObject(retObj, (*all_pyclass)[i].class_real_name.c_str(), (PyObject *)&(*all_pyclass)[i].pytype_def); - } - - return retObj; - } - }; - PyImport_AppendInittab(m_mod_name.c_str(), TmpLambda::PyInit_emb); - - return 0; -} - -void ffpython_t::init_method() -{ - std::string mod_name_ = m_mod_name; - std::string doc_ = m_mod_doc; - - if (m_pymethod_defs.empty()) - { - m_pymethod_defs.reserve(m_func_info.size() + 1); - - for (size_t i = 0; i < m_func_info.size(); ++i) - { - PyMethodDef tmp = { m_func_info[i].func_impl_name.c_str(), m_func_info[i].func, - METH_VARARGS, m_func_info[i].doc_impl.c_str() }; - m_pymethod_defs.push_back(tmp); - } - PyMethodDef tmp = { NULL }; - m_pymethod_defs.push_back(tmp); - } - - return; -} -void ffpython_t::rename_method() -{ - for (size_t i = 0; i < m_func_info.size(); ++i) - { - std::string pystr_args; - std::string pystr_args_only_name; - for (int j = 0; j < m_func_info[i].args_num; ++j) - { - std::stringstream ss; - if (pystr_args.empty()) - { - ss << "a" << (j+1); - pystr_args += ss.str(); - } - else - { - ss << ", a" << (j+1); - pystr_args += ss.str(); - } - } - pystr_args_only_name = pystr_args; - for (int j = 0; j < m_func_info[i].option_args_num; ++j) - { - std::stringstream ss; - if (pystr_args.empty()) - { - ss << "a" << (m_func_info[i].args_num + j+1); - std::string tmp = ss.str(); - pystr_args_only_name += tmp; - pystr_args += tmp + " = None"; - } - else - { - ss << ", a" << (m_func_info[i].args_num + j+1); - std::string tmp = ss.str(); - pystr_args_only_name += tmp; - pystr_args += tmp + " = None"; - } - } - if (!pystr_args_only_name.empty()) - pystr_args_only_name += ","; - - std::stringstream oss;//创建一个流 - oss << m_func_info[i].func_addr;//把值传递如流中 - std::string funcAddrStr = oss.str();//获取转换后的字符转并将其写入result - - char buff[1024]; - SAFE_SPRINTF(buff, sizeof(buff), - "_tmp_ff_ = None\nif '%s' in globals():\n\t_tmp_ff_ = globals()['%s']\n" - "def %s(%s):\n" - "\t'''%s'''\n" - "\treturn %s.%s(%s,(%s))\n" - "import %s\n" - "%s.%s = %s\n" - "%s = None\n" - "if _tmp_ff_:\n\tglobals()['%s'] = _tmp_ff_\n_tmp_ff_ = None\n", - m_func_info[i].func_name.c_str(), m_func_info[i].func_name.c_str(), - m_func_info[i].func_name.c_str(), pystr_args.c_str(), - m_func_info[i].doc.c_str(), - m_mod_name.c_str(), m_func_info[i].func_impl_name.c_str(), funcAddrStr.c_str(), pystr_args_only_name.c_str(), - m_mod_name.c_str(), - m_mod_name.c_str(), m_func_info[i].func_name.c_str(), m_func_info[i].func_name.c_str(), - m_func_info[i].func_name.c_str(), - m_func_info[i].func_name.c_str() - ); - - //printf(buff); - PyRun_SimpleString(buff); - } -} - -int ffpython_t::init_pyclass() -{ - for (size_t i = 0; i < m_all_pyclass.size(); ++i) - { - m_all_pyclass[i].static_pytype_info->mod_name = m_mod_name; - if (false == m_all_pyclass[i].inherit_name.empty()) - { - pyclass_regigster_tool_t* inherit_class = get_pyclass_info_by_name(m_all_pyclass[i].inherit_name); - assert(inherit_class && "base class must be registed"); - for (size_t n = 0; n < inherit_class->methods_info.size(); ++n) - { - const std::string& method_name = inherit_class->methods_info[n].func_name; - if (false == is_method_exist(m_all_pyclass[i].methods_info, method_name)) - { - m_all_pyclass[i].methods_info.push_back(inherit_class->methods_info[n]); - } - } - for (size_t n = 0; n < inherit_class->propertys_info.size(); ++n) - { - const std::string& property_name = inherit_class->propertys_info[n].property_name; - if (false == is_property_exist(m_all_pyclass[i].propertys_info, property_name)) - { - m_all_pyclass[i].propertys_info.push_back(inherit_class->propertys_info[n]); - } - } - } - //! init class property - for (size_t j = 0; j < m_all_pyclass[i].propertys_info.size(); ++j) - { - PyGetSetDef tmp = {(char*)m_all_pyclass[i].propertys_info[j].property_name.c_str(), - m_all_pyclass[i].propertys_info[j].getter_func, - m_all_pyclass[i].propertys_info[j].setter_func, - (char*)m_all_pyclass[i].propertys_info[j].doc.c_str(), - m_all_pyclass[i].propertys_info[j].ptr - }; - m_all_pyclass[i].pyproperty_def.push_back(tmp); - } - PyGetSetDef tmp_property_def = {NULL}; - m_all_pyclass[i].pyproperty_def.push_back(tmp_property_def); - //! init class method - for (size_t j = 0; j < m_all_pyclass[i].methods_info.size(); ++j) - { - PyMethodDef tmp = {m_all_pyclass[i].methods_info[j].func_real_name.c_str(), - m_all_pyclass[i].methods_info[j].func, - METH_VARARGS, - m_all_pyclass[i].methods_info[j].doc.c_str() - }; - m_all_pyclass[i].pymethod_def.push_back(tmp); - - } - PyMethodDef tmp_del = {"delete", - m_all_pyclass[i].delete_func, - METH_VARARGS, - "delete obj" - }; - m_all_pyclass[i].pymethod_def.push_back(tmp_del); - PyMethodDef tmp_method_def = {NULL}; - m_all_pyclass[i].pymethod_def.push_back(tmp_method_def); - - m_all_pyclass[i].class_name_with_mod = m_mod_name + "." + m_all_pyclass[i].class_name; - m_all_pyclass[i].class_reel_name_with_mod = m_mod_name + "." + m_all_pyclass[i].class_real_name; - - PyTypeObject tmp_pytype_def = - { - PyVarObject_HEAD_INIT(NULL, 0) - m_all_pyclass[i].class_reel_name_with_mod.c_str(), /*tp_name*/ - m_all_pyclass[i].type_size, /*tp_size*/ - 0, /*tp_itemsize*/ - (destructor)m_all_pyclass[i].dector, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - m_all_pyclass[i].doc.c_str(), /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - &(m_all_pyclass[i].pymethod_def.front()),//Noddy_methods, /* tp_methods */ - 0,//Noddy_members, /* tp_members */ - &(m_all_pyclass[i].pyproperty_def.front()),//Noddy_getseters, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)m_all_pyclass[i].init, /* tp_init */ - 0, /* tp_alloc */ - m_all_pyclass[i].ctor, /* tp_new */ - }; - m_all_pyclass[i].pytype_def = tmp_pytype_def; - m_all_pyclass[i].static_pytype_info->pytype_def = &m_all_pyclass[i].pytype_def; - cpp_to_pyclass_reg_info_t::add(m_all_pyclass[i].class_name, m_all_pyclass[i].inherit_name, &m_all_pyclass[i].pytype_def); - } - - return 0; -} - -void ffpython_t::rename_pyclass() -{ - for (size_t i = 0; i < m_all_pyclass.size(); ++i) - { - std::stringstream str_def_args; - std::stringstream str_init_args; - for (int a = 0; a < m_all_pyclass[i].args_num; ++a) - { - str_def_args << "a" << (a + 1) << ","; - str_init_args << "a" << (a + 1) << ","; - } - for (int b = 0; b < m_all_pyclass[b].option_args_num; ++b) - { - str_def_args << "a" << (m_all_pyclass[i].args_num + b + 1) << " = None,"; - str_init_args << "a" << (m_all_pyclass[i].args_num + b + 1) << ","; - } - - char buff[1024]; - SAFE_SPRINTF(buff, sizeof(buff), - "_tmp_ff_ = None\nif '%s' in globals():\n\t_tmp_ff_ = globals()['%s']\n" - "import %s\n" - "class %s(object):\n" - "\t'''%s'''\n" - "\tdef __init__(self, %s assign_obj_ = 0):\n" - "\t\t'''%s'''\n" - "\t\tif True == isinstance(assign_obj_, %s):\n" - "\t\t\tself.obj = assign_obj_\n" - "\t\t\treturn\n" - "\t\tself.obj = %s(0,(%s))\n", - m_all_pyclass[i].class_name.c_str(), m_all_pyclass[i].class_name.c_str(), - m_mod_name.c_str(), - m_all_pyclass[i].class_name.c_str(), - m_all_pyclass[i].doc.c_str(), - str_def_args.str().c_str(), - "init class", - m_all_pyclass[i].class_reel_name_with_mod.c_str(), - m_all_pyclass[i].class_reel_name_with_mod.c_str(), str_init_args.str().c_str() - ); - - std::string gen_class_str = buff; - SAFE_SPRINTF(buff, sizeof(buff), - "\tdef delete(self):\n" - "\t\t'''delete obj'''\n" - "\t\tself.obj.delete()\n"); - gen_class_str += buff; - //! 增加析构函数 - //! 增加属性 - for (size_t c = 0; c < m_all_pyclass[i].propertys_info.size(); ++c) - { - SAFE_SPRINTF(buff, sizeof(buff), - "\tdef get_%s(self):\n" - "\t\treturn self.obj.%s\n" - "\tdef set_%s(self, v):\n" - "\t\tself.obj.%s = v\n" - "\t@property\n" - "\tdef %s(self):\n" - "\t\treturn self.obj.%s\n" - "\t@%s.setter\n" - "\tdef %s(self, v):\n" - "\t\tself.obj.%s = v\n", - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str(), - m_all_pyclass[i].propertys_info[c].property_name.c_str() - ); - gen_class_str += buff; - } - - for (size_t m = 0; m < m_all_pyclass[i].methods_info.size(); ++m) - { - std::string pystr_args; - std::string pystr_args_only_name; - for (int j = 0; j < m_all_pyclass[i].methods_info[m].args_num; ++j) - { - std::stringstream ss; - if (pystr_args.empty()) - { - ss << "a" << (j + 1); - pystr_args += ss.str(); - } - else - { - ss << ", a" << (j + 1); - pystr_args += ss.str(); - } - } - pystr_args_only_name = pystr_args; - for (int j = 0; j < m_all_pyclass[i].methods_info[m].option_args_num; ++j) - { - std::stringstream ss; - if (pystr_args.empty()) - { - ss << "a" << (m_all_pyclass[i].methods_info[m].args_num + j + 1); - std::string tmp = ss.str(); - pystr_args_only_name += tmp; - pystr_args += tmp + " = None"; - } - else - { - ss << ", a" << (m_all_pyclass[i].methods_info[m].args_num + j + 1); - std::string tmp = ss.str(); - pystr_args_only_name += tmp; - pystr_args += tmp + " = None"; - } - } - if (!pystr_args_only_name.empty()) - pystr_args_only_name += ","; - - std::stringstream oss;//创建一个流 - oss << m_all_pyclass[i].methods_info[m].func_addr;//把值传递如流中 - std::string funcAddrStr = oss.str();//获取转换后的字符转并将其写入result - - SAFE_SPRINTF(buff, sizeof(buff), - "\tdef %s(self,%s):\n" - "\t\t'''%s'''\n" - "\t\treturn self.obj.%s(%s,(%s))\n" - , m_all_pyclass[i].methods_info[m].func_name.c_str(), pystr_args.c_str(), - m_all_pyclass[i].methods_info[m].doc.c_str(), - m_all_pyclass[i].methods_info[m].func_real_name.c_str(), funcAddrStr.c_str(), pystr_args_only_name.c_str() - ); - gen_class_str += buff; - } - SAFE_SPRINTF(buff, sizeof(buff), - "%s.%s = %s\n" - "%s = None\n" - "if _tmp_ff_:\n\tglobals()['%s'] = _tmp_ff_\n_tmp_ff_ = None\n", - m_mod_name.c_str(), m_all_pyclass[i].class_name.c_str(), m_all_pyclass[i].class_name.c_str(), - m_all_pyclass[i].class_name.c_str(), - m_all_pyclass[i].class_name.c_str() - ); - gen_class_str += buff; - //printf(gen_class_str.c_str()); - PyRun_SimpleString(gen_class_str.c_str()); - } -} - -bool ffpython_t::is_method_exist(const std::vector& src_, const std::string& new_) -{ - for (size_t i = 0; i < src_.size(); ++i) - { - if (new_ == src_[i].func_name) - { - return true; - } - } - return false; -} -bool ffpython_t::is_property_exist(const std::vector& src_, const std::string& new_) -{ - for (size_t i = 0; i < src_.size(); ++i) - { - if (new_ == src_[i].property_name) - { - return true; - } - } - return false; -} -pyclass_regigster_tool_t* ffpython_t::get_pyclass_info_by_name(const std::string& name_) -{ - for (size_t i = 0; i < m_all_pyclass.size(); ++i) - { - if (m_all_pyclass[i].class_name == name_) - { - return &(m_all_pyclass[i]); - } - } - return NULL; -} - + +#include "ffpython.h" +using namespace ff; + +std::vector FFPython::m_regFuncs; +std::map FFPython::m_allocObjs; +PyObject* FFPython::pyobjBuildTmpObj = NULL; +static PyObject* callExt(PyObject* self, PyObject* args) +{ + size_t idFunc = 0; + int64_t addrObj = 0; + int nOps = 0; + int nAutoRelease = 0; + PyObject* pyArgList = NULL; + if (!PyArg_ParseTuple(args, "LiO|ii", &addrObj, &idFunc, &pyArgList, &nOps, &nAutoRelease) || pyArgList == NULL) + return NULL; + ScriptIterface* pfunc = FFPython::getRegFuncByID(idFunc); + if (!pfunc) { + Py_RETURN_NONE; + } + pfunc->clearTmpArg();//!ֵ֧ݹ + pfunc->pobjArg = (void*)addrObj;//!෽Ҫָ + ScriptCppOps >::scriptToCpp(pyArgList, pfunc->tmpArgs); + if (nOps != E_CLASS_DEL && pfunc->tmpArgs.size() < pfunc->nMinArgs) + { + char buff[256] = { 0 }; + SAFE_SPRINTF(buff, sizeof(buff), "args num error func:%s, expect:%d, given:%d", + pfunc->strName.c_str(), pfunc->nMinArgs, (int)pfunc->tmpArgs.size()); + PyErr_SetString(PyExc_TypeError, buff); + pfunc->clearTmpArg(); + return NULL; + } + PyObject* ret = NULL; + if (nOps == E_STATIC_FUNC) { + ret = pfunc->handleRun(); + } + else if (nOps == E_CLASS_NEW) { + void* pObjNew = pfunc->handleNew(); + FFPython::m_allocObjs[pObjNew] = pfunc; + ret = ScriptCppOps::scriptFromCpp(pObjNew); + } + else if (nOps == E_CLASS_DEL) { + std::map::iterator it = FFPython::m_allocObjs.find(pfunc->pobjArg); + if (it != FFPython::m_allocObjs.end()) { + FFPython::m_allocObjs.erase(it); + pfunc->handleDel(); + } + } + else if (nOps == E_CLASS_METHOD || nOps == E_CLASS_FIELD) { + if (nAutoRelease)//!pythonĶ֤һָЧ + { + std::map::iterator it = FFPython::m_allocObjs.find(pfunc->pobjArg); + if (it == FFPython::m_allocObjs.end()) { + Py_RETURN_NONE; + } + } + ret = pfunc->handleRun(); + } + pfunc->clearTmpArg(); + if (nOps == 2) + Py_RETURN_NONE; + return ret; +} + +static PyMethodDef EmbMethods[] = { + {"callExt", callExt, METH_VARARGS, "ffpython internal func"}, + {NULL, NULL, 0, NULL} +}; + +FFPython::FFPython() +{ +#ifdef PYTHON_3 + if (Py_IsInitialized()) { + return; + } + struct PyInitTmpTool + { + static PyObject* PyInit_emb(void) + { + static PyModuleDef EmbModule = { + PyModuleDef_HEAD_INIT, "ffpython", NULL, -1, EmbMethods, + NULL, NULL, NULL, NULL + }; + return PyModule_Create(&EmbModule); + } + }; + PyImport_AppendInittab("ffpython", &PyInitTmpTool::PyInit_emb); + Py_Initialize(); +#else + Py_Initialize(); + Py_InitModule3("ffpython", EmbMethods, ""); +#endif + addPath("./"); + + runCode("import ffpython"); + { + const char* strCode = "\ +def regFuncExt(idFunc, name): \n\ + import ffpython \n\ + callCppFunc = ffpython.callExt \n\ + def funReal(*args): \n\ + return callCppFunc(0, idFunc, args, 0) \n\ + setattr(ffpython, name, funReal) \n\ + return True \n\ +ffpython.regFuncExt = regFuncExt \n\ +"; + runCode(strCode); + } + { + const char* strCode = "\ +def regMethodExt(idFunc, name, nameClass) : \n\ + import ffpython \n\ + classType = getattr(ffpython, nameClass, None) \n\ + if not classType: \n\ + return False \n\ + callCppFunc = ffpython.callExt \n\ + def funReal(self, *args): \n\ + return callCppFunc(self._cppInterObj_, idFunc, args, 0, self._autoRelease_) \n\ + setattr(classType, name, funReal) \n\ + return True \n\ +ffpython.regMethodExt = regMethodExt \n\ +"; + runCode(strCode); + } + { + const char* strCode = "\ +def regFieldExt(nFuncID, fieldName, className): \n\ + classType = getattr(ffpython, className, None) \n\ + callExt = ffpython.callExt \n\ + def getFieldVal(self) : \n\ + return callExt(self._cppInterObj_, nFuncID, (), 4) \n\ + def setFieldVal(self, value) : \n\ + return callExt(self._cppInterObj_, nFuncID, (value,), 4) \n\ + setattr(classType, fieldName, property(getFieldVal, setFieldVal))#add property \n\ + return \n\ +ffpython.regFieldExt = regFieldExt \n\ +"; + runCode(strCode); + } + { + const char* strCode = "\ +def buildTmpObj(className, ptr) : \n\ + srcType = getattr(ffpython, className, None)\n\ + if srcType : \n\ + return srcType(cppTmpPtr = ptr) \n\ + return None \n\ +ffpython.buildTmpObj = buildTmpObj \n\ +"; + runCode(strCode); + } + FFPython::pyobjBuildTmpObj = getScriptVar("ffpython", "buildTmpObj"); +} +FFPython::~FFPython() +{ + if (Py_IsInitialized()) + Py_Finalize(); +} +void FFPython::addPath(const std::string& path) +{ + char buff[1024]; + SAFE_SPRINTF(buff, sizeof(buff), "import sys\nif '%s' not in sys.path:\n\tsys.path.append('%s')\n", path.c_str(), path.c_str()); + runCode(buff); +} +void FFPython::runCode(const std::string& code) +{ + PyRun_SimpleString(code.c_str()); + if (PyErr_Occurred()) { + traceback(m_strErr); + } +} +PyObject* FFPython::callFuncByObj(PyObject* pFunc, std::vector& objArgs) +{ + PyObject* pValue = NULL; + if (pFunc && PyCallable_Check(pFunc)) { + PyObject* pArgs = PyTuple_New(objArgs.size()); + for (int i = 0; i < objArgs.size(); ++i) { + PyTuple_SetItem(pArgs, i, objArgs[i]); + } + objArgs.clear(); + pValue = PyObject_CallObject(pFunc, pArgs); + Py_DECREF(pArgs); + } + else { + for (int i = 0; i < objArgs.size(); ++i) { + Py_DECREF(objArgs[i]); + } + objArgs.clear(); + } + if (PyErr_Occurred()) { + traceback(m_strErr); + } + + if (!pValue) + Py_RETURN_FALSE; + return pValue; +} +PyObject* FFPython::getScriptVarByObj(PyObject* pModule, const std::string& strVarName) +{ + PyObject* pValue = PyObject_GetAttrString(pModule, strVarName.c_str()); + if (!pValue) { + Py_RETURN_NONE; + } + return pValue; +} +PyObject* FFPython::getScriptVar(const std::string& strMod, const std::string& strVarName) +{ + PyObject* pName = PyString_FromString(strMod.c_str()); + if (!pName) + Py_RETURN_FALSE; + PyObject* pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (!pModule) { + Py_RETURN_NONE; + } + PyObject* pValue = getScriptVarByObj(pModule, strVarName); + Py_DECREF(pModule); + return pValue; +} +PyObject* FFPython::callFunc(const std::string& modName, const std::string& funcName, std::vector& objArgs) +{ + PyObject* pFunc = getScriptVar(modName, funcName); + PyObject* pValue = callFuncByObj(pFunc, objArgs); + Py_XDECREF(pFunc); + + if (!pValue) + Py_RETURN_FALSE; + return pValue; +} +FFPython& FFPython::reg(ScriptIterface* pObj, const std::string& name, + int nOps, std::string nameClass, std::string nameInherit) { + FFPython::m_regFuncs.push_back(pObj); + FFPython::m_regFuncs.back()->strName = name; + if (nOps == E_STATIC_FUNC) { + call("ffpython", "regFuncExt", FFPython::m_regFuncs.size() - 1, name); + } + else if (nOps == E_CLASS_NEW) { + m_curRegClassName = nameClass; + int idFunc = (int)FFPython::m_regFuncs.size() - 1; + std::string strBaseInit; + if (nameInherit.empty() == false) { + nameInherit = std::string("(") + nameInherit + ")"; + strBaseInit = nameInherit + ".__init__(self,cppTmpPtr=1)"; + } + char buff[1024*2]; + SAFE_SPRINTF(buff, sizeof(buff), "\ +class %s%s: \n\ + def __init__(self, *args, **opt) : \n\ + %s \n\ + self._autoRelease_ = 0 \n\ + self._cppInterObj_ = opt.get('cppTmpPtr', 0) \n\ + if not self._cppInterObj_ : \n\ + self._cppInterObj_ = ffpython.callExt(0, %d, args, 1) \n\ + self._autoRelease_ = 1 \n\ + def __del__(self) : \n\ + if self._autoRelease_ : \n\ + ffpython.callExt(self._cppInterObj_, %d, (), 2) \n\ + def __repr__(self): \n\ + return ''%%(self._cppInterObj_) \n\ + def __str__(self): \n\ + return ''%%(self._cppInterObj_) \n\ +ffpython.%s = %s \n\ +", nameClass.c_str(), nameInherit.c_str(), strBaseInit.c_str(), idFunc, idFunc, + nameClass.c_str(), nameClass.c_str(), + nameClass.c_str(), nameClass.c_str()); + runCode(buff); + } + else if (nOps == E_CLASS_METHOD) { + if (nameClass.empty()) + nameClass = m_curRegClassName; + call("ffpython", "regMethodExt", FFPython::m_regFuncs.size() - 1, name, nameClass); + } + else if (nOps == E_CLASS_FIELD) { + if (nameClass.empty()) + nameClass = m_curRegClassName; + call("ffpython", "regFieldExt", FFPython::m_regFuncs.size() - 1, name, nameClass); + } + return *this; +} +int FFPython::traceback(std::string& ret_) +{ + ret_.clear(); + PyObject* err = PyErr_Occurred(); + if (!err) + { + return 0; + } + + PyObject* ptype = NULL, * pvalue = NULL, * ptraceback = NULL; + PyObject* pyth_module = NULL, * pyth_func = NULL; + + PyErr_Fetch(&ptype, &pvalue, &ptraceback); + if (pvalue) + { + if (true == PyList_Check(pvalue)) + { + int64_t n = PyList_Size(pvalue); + for (int64_t i = 0; i < n; ++i) + { + PyObject* pystr = PyObject_Str(PyList_GetItem(pvalue, i)); + ret_ += PyString_AsString(pystr); + ret_ += "\n"; + Py_DECREF(pystr); + } + } + else if (true == PyTuple_Check(pvalue)) + { + int64_t n = PyTuple_Size(pvalue); + for (int64_t i = 0; i < n; ++i) + { + PyObject* tmp_str = PyTuple_GetItem(pvalue, i); + if (true == PyTuple_Check(tmp_str)) + { + int64_t m = PyTuple_Size(tmp_str); + for (int64_t j = 0; j < m; ++j) + { + PyObject* pystr = PyObject_Str(PyTuple_GetItem(tmp_str, j)); + ret_ += PyString_AsString(pystr); + ret_ += ","; + Py_DECREF(pystr); + } + } + else + { + PyObject* pystr = PyObject_Str(tmp_str); + ret_ += PyString_AsString(pystr); + Py_DECREF(pystr); + } + ret_ += "\n"; + } + } + else + { + PyObject* pystr = PyObject_Str(pvalue); + if (pystr) + { + ret_ += PyString_AsString(pystr); + ret_ += "\n"; + Py_DECREF(pystr); + } + } + } + + /* See if we can get a full traceback */ + PyObject* module_name = PyString_FromString("traceback"); + pyth_module = PyImport_Import(module_name); + Py_DECREF(module_name); + + if (pyth_module && ptype && pvalue && ptraceback) + { + pyth_func = PyObject_GetAttrString(pyth_module, "format_tb"); + if (pyth_func && PyCallable_Check(pyth_func)) { + PyObject* pArgs = PyTuple_New(1); + PyTuple_SetItem(pArgs, 0, ptraceback); + PyObject* pyth_val = PyObject_CallObject(pyth_func, pArgs); + if (pyth_val && true == PyList_Check(pyth_val)) + { + int64_t n = PyList_Size(pyth_val); + for (int64_t i = 0; i < n; ++i) + { + PyObject* tmp_str = PyList_GetItem(pyth_val, i); + PyObject* pystr = PyObject_Str(tmp_str); + if (pystr) + { + ret_ += PyString_AsString(pystr); + + Py_DECREF(pystr); + } + ret_ += "\n"; + } + } + else { + PyErr_Print(); + } + Py_XDECREF(pArgs); + Py_XDECREF(pyth_val); + } + } + Py_XDECREF(pyth_func); + Py_XDECREF(pyth_module); + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + PyErr_Clear(); + printf("ffpython traceback:%s\n", ret_.c_str()); + return 0; +} \ No newline at end of file diff --git a/ffpython.h b/ffpython.h index 47bf0ce..a89a225 100644 --- a/ffpython.h +++ b/ffpython.h @@ -1,492 +1,1773 @@ -#ifndef __FFPYTHON_H_ -#define __FFPYTHON_H_ - -#ifdef _DEBUG -#undef _DEBUG -#include -#define _DEBUG -#else -#include -#endif -#include - -#include - - -#include "pyops_base.h" -#include "pyops_for_embed.h" -#include "pyops_for_extend.h" - -class ffpython_t -{ -public: - typedef std::string (*ModInitFunc)(ffpython_t&); - - struct reg_info_t - { - reg_info_t():args_num(0),option_args_num(0),func_addr(0){} - int args_num; - int option_args_num; - PTR_NUMBER func_addr; - PyCFunction func; - std::string func_name; - std::string func_impl_name; - std::string doc; - std::string doc_impl; - }; - -public: - ffpython_t(ModInitFunc func = NULL); - ~ffpython_t(); - - static int init_py(); - static int final_py(); - - static int add_path(const std::string& path_); - - static int run_string(const std::string& py_); - static int reload(const std::string& py_name_); - static int load(const std::string& py_name_); - - - - //! 注册static function, - template - ffpython_t& reg(T func_, const std::string& func_name_, std::string doc_ = "") - { - reg_info_t tmp; - tmp.args_num = pyext_func_traits_t::args_num(); - tmp.option_args_num = pyext_func_traits_t::option_args_num(); - tmp.func = (PyCFunction)pyext_func_traits_t::pyfunc; - tmp.func_name= func_name_; - tmp.func_impl_name = func_name_ + "_internal_"; - tmp.doc = doc_; - tmp.doc_impl = std::string("internal use, please call ") + func_name_; - tmp.func_addr= (PTR_NUMBER)func_; - - m_func_info.push_back(tmp); - return *this; - } - - //! 注册c++ class - template - pyclass_regigster_tool_t& reg_class(const std::string& class_name_, std::string doc_ = "", std::string inherit_name_ = "") - { - if (pyclass_base_info_t::pytype_info.class_name.empty() == false) - throw std::runtime_error("this type has been registed"); - - pyclass_base_info_t::pytype_info.class_name = class_name_; - //pyclass_base_info_t::pytype_info.mod_name = m_mod_name; - pyclass_base_info_t::pytype_info.total_args_num = pyext_func_traits_t::args_num() + - pyext_func_traits_t::option_args_num(); - - pyclass_regigster_tool_t tmp; - tmp.class_name = class_name_; - tmp.class_real_name = class_name_ + "_internal_"; - tmp.inherit_name = inherit_name_; - tmp.doc = doc_; - tmp.dector = (destructor)pyclass_base_info_t::free_obj; - tmp.init = (initproc)pyclass_ctor_tool_t::init_obj; - tmp.ctor = pyclass_base_info_t::alloc_obj; - tmp.type_size = sizeof(typename pyclass_base_info_t::obj_data_t); - tmp.args_num = pyext_func_traits_t::args_num(); - tmp.option_args_num = pyext_func_traits_t::option_args_num(); - tmp.static_pytype_info = &(pyclass_base_info_t::pytype_info); - //! 注册析构函数,python若不调用析构函数,当对象被gc时自动调用 - tmp.delete_func = (PyCFunction)pyclass_base_info_t::release; - m_all_pyclass.push_back(tmp); - - return m_all_pyclass.back(); - } - - - //! 调用python函数,最多支持9个参数 - template - RET_V call(const std::string& mod_name_, const std::string& func_) - { - pycall_arg_t args(0); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const std::string& mod_name_, const std::string& func_, const ARG1& a1) - { - pycall_arg_t args(1); - args.add(a1); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const std::string& mod_name_, const std::string& func_, const ARG1& a1, const ARG2& a2) - { - pycall_arg_t args(2); - args.add(a1).add(a2); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const std::string& mod_name_, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3) - { - pycall_arg_t args(3); - args.add(a1).add(a2).add(a3); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const std::string& mod_name_, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) - { - pycall_arg_t args(4); - args.add(a1).add(a2).add(a3).add(a4); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const std::string& mod_name_, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5) - { - pycall_arg_t args(5); - args.add(a1).add(a2).add(a3).add(a4).add(a5); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const std::string& mod_name_, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5,const ARG6& a6) - { - pycall_arg_t args(6); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const std::string& mod_name_, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5,const ARG6& a6,const ARG7& a7) - { - pycall_arg_t args(7); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const std::string& mod_name_, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) - { - pycall_arg_t args(8); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - template - RET_V call(const std::string& mod_name_, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) - { - pycall_arg_t args(9); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8).add(a9); - pytype_tool_impl_t pyret; - return pycall_t::call(mod_name_, func_, args, pyret); - } - //!call python class method begin****************************************************************** - template - RET_V obj_call(PyObject* pobj, const std::string& func_) - { - pycall_arg_t args(0); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const std::string& func_, const ARG1& a1) - { - pycall_arg_t args(1); - args.add(a1); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const std::string& func_, const ARG1& a1, const ARG2& a2) - { - pycall_arg_t args(2); - args.add(a1).add(a2); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3) - { - pycall_arg_t args(3); - args.add(a1).add(a2).add(a3); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) - { - pycall_arg_t args(4); - args.add(a1).add(a2).add(a3).add(a4); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5) - { - pycall_arg_t args(5); - args.add(a1).add(a2).add(a3).add(a4).add(a5); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5,const ARG6& a6) - { - pycall_arg_t args(6); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5,const ARG6& a6,const ARG7& a7) - { - pycall_arg_t args(7); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) - { - pycall_arg_t args(8); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - template - RET_V obj_call(PyObject* pobj, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) - { - pycall_arg_t args(9); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8).add(a9); - pytype_tool_impl_t pyret; - return pycall_t::call_obj_method(pobj, func_, args, pyret); - } - //!call python class method end****************************************************************** - - //!call python lambad function begin ############################################################ - template - RET_V call_lambda(PyObject* pobj) - { - pycall_arg_t args(0); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1) - { - pycall_arg_t args(1); - args.add(a1); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2) - { - pycall_arg_t args(2); - args.add(a1).add(a2); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3) - { - pycall_arg_t args(3); - args.add(a1).add(a2).add(a3); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4) - { - pycall_arg_t args(4); - args.add(a1).add(a2).add(a3).add(a4); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5) - { - pycall_arg_t args(5); - args.add(a1).add(a2).add(a3).add(a4).add(a5); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5,const ARG6& a6) - { - pycall_arg_t args(6); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5,const ARG6& a6,const ARG7& a7) - { - pycall_arg_t args(7); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8) - { - pycall_arg_t args(8); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - template - RET_V call_lambda(PyObject* pobj, const std::string& func_, const ARG1& a1, const ARG2& a2, const ARG3& a3, const ARG4& a4, - const ARG5& a5, const ARG6& a6, const ARG7& a7, const ARG8& a8, const ARG9& a9) - { - pycall_arg_t args(9); - args.add(a1).add(a2).add(a3).add(a4).add(a5).add(a6).add(a7).add(a8).add(a9); - pytype_tool_impl_t pyret; - return pycall_t::call_lambda(pobj, args, pyret); - } - //!call python lambad function ennd ############################################################ - template - RET_V get_global_var(const std::string& mod_name_, const std::string& var_name_) - { - PyObject *pName = NULL, *pModule = NULL; - std::string err_msg; - - pName = PyString_FromString(mod_name_.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - pyops_t::traceback(err_msg); - throw std::runtime_error(err_msg.c_str()); - } - - pytype_tool_impl_t pyret; - PyObject *pvalue = PyObject_GetAttrString(pModule, var_name_.c_str()); - Py_DECREF(pModule); - - if (!pvalue) - { - pyops_t::traceback(err_msg); - throw std::runtime_error(err_msg.c_str()); - } - - if (pyret.parse_value(pvalue)) - { - Py_XDECREF(pvalue); - throw std::runtime_error("type invalid"); - } - Py_XDECREF(pvalue); - return pyret.get_value(); - } - - template - int set_global_var(const std::string& mod_name_, const std::string& var_name_, const T& val_) - { - PyObject *pName = NULL, *pModule = NULL; - std::string err_msg; - - pName = PyString_FromString(mod_name_.c_str()); - pModule = PyImport_Import(pName); - Py_DECREF(pName); - if (NULL == pModule) - { - pyops_t::traceback(err_msg); - throw std::runtime_error(err_msg.c_str()); - } - - PyObject* pval = pytype_traits_t::pyobj_from_cppobj(val_); - int ret = PyObject_SetAttrString(pModule, var_name_.c_str(), pval); - Py_DECREF(pModule); - - return ret != -1? 0: -1; - } - - template - RET_V getattr(PyObject* pModule, const std::string& var_name_) - { - std::string err_msg; - if (NULL == pModule) - { - throw std::runtime_error("getattr object ptr null"); - } - - pytype_tool_impl_t pyret; - PyObject *pvalue = PyObject_GetAttrString(pModule, var_name_.c_str()); - - if (!pvalue) - { - pyops_t::traceback(err_msg); - throw std::runtime_error(err_msg.c_str()); - } - - if (pyret.parse_value(pvalue)) - { - Py_XDECREF(pvalue); - throw std::runtime_error("type invalid"); - } - Py_XDECREF(pvalue); - return pyret.get_value(); - } - - - void cache_pyobject(PyObject* pobj) - { - m_cache_pyobject.push_back(pobj); - } - void clear_cache_pyobject() - { - if (Py_IsInitialized()) - { - for (size_t i = 0; i < m_cache_pyobject.size(); ++i) - { - Py_XDECREF(m_cache_pyobject[i]); - } - m_cache_pyobject.clear(); - } - } -private: - //! 将需要注册的函数、类型注册到python虚拟机 - int init(const std::string& mod_name_, std::string doc_ = ""); - void init_method(); - void rename_method(); - int init_pyclass(); - void rename_pyclass(); - - - bool is_method_exist(const std::vector& src_, const std::string& new_); - bool is_property_exist(const std::vector& src_, const std::string& new_); - pyclass_regigster_tool_t* get_pyclass_info_by_name(const std::string& name_); - -private: - std::string m_mod_name; - std::string m_mod_doc; - std::vector m_pymethod_defs; - std::vector m_func_info; - - //! reg class - std::vector m_all_pyclass; - //! cache some pyobject for optimize - std::vector m_cache_pyobject; -}; - - -#endif +#ifndef _FFPYTHON_H_ +#define _FFPYTHON_H_ + +#define PY_SSIZE_T_CLEAN +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +namespace ff +{ +#ifndef PyString_Check + #define PYTHON_3 + #define PyString_Check PyUnicode_Check + #define PyString_AsString(pvalue_) PyUnicode_AsUTF8(pvalue_) + #define PyString_AsStringAndSize(pvalue_, pDestPtr, nLen) *pDestPtr = PyUnicode_AsUTF8AndSize(pvalue_, nLen) + #define PyString_FromStringAndSize PyUnicode_FromStringAndSize + #define PyString_FromString PyUnicode_FromString +#endif +#ifdef _WIN32 +#define SAFE_SPRINTF _snprintf_s +#define PTR_NUMBER int64_t +#else +#define SAFE_SPRINTF snprintf +#define PTR_NUMBER int64_t +#endif +#define PYCTOR int (*) +template +struct ScriptCppOps; + +template struct CheckType { static bool IsScriptObject() { return false; } }; +template<> struct CheckType { static bool IsScriptObject() { return true; } }; +struct ScriptObjRefGuard +{ + ScriptObjRefGuard(bool b, PyObject* v) :bNoDec(b),value(v){} + ~ScriptObjRefGuard() { + if (bNoDec == false) + Py_XDECREF(value); + value = NULL; + //printf("ref dec!!!!\n"); + } + bool bNoDec; + PyObject* value; +}; + +template struct RetTraitUtil { typedef T RET_TYPE; }; +template<> struct RetTraitUtil { typedef bool RET_TYPE; }; +template struct InitValueTrait { static T value() { return T(); } }; +template <> struct InitValueTrait { static const char* value() { return ""; } }; +template <> struct InitValueTrait { static const char* value() { return ""; } }; + +#define RET_V typename RetTraitUtil::RET_TYPE + +class ScriptIterface +{ +public: + ScriptIterface(int n = 0):pobjArg(NULL), nMinArgs(n){} + virtual ~ScriptIterface() {} + PyObject* arg(size_t i) { + if (i <= tmpArgs.size()) + return tmpArgs[i - 1]; + return Py_None; + } + void clearTmpArg() { + pobjArg = NULL; + tmpArgs.clear(); + } + virtual PyObject* handleRun() { Py_RETURN_NONE; } + virtual void* handleNew() { return NULL; } + virtual void handleDel() { } +public: + void* pobjArg; + int nMinArgs;//!ٲ + std::string strName; + std::vector tmpArgs; +}; +template +class ScriptFuncImpl; +template +class ScriptClassImpl; +template +class ScriptMethodImpl; +template +class ScriptFieldImpl; + +enum FFScriptTypeDef { + E_STATIC_FUNC = 0, + E_CLASS_NEW = 1, + E_CLASS_DEL = 2, + E_CLASS_METHOD = 3, + E_CLASS_FIELD = 4 +}; + +class FFPython +{ +public: + FFPython(); + ~FFPython(); + void addPath(const std::string& path); + void runCode(const std::string& code); + + FFPython& reg(ScriptIterface* pObj, const std::string& name, + int nOps, std::string nameClass = "", std::string nameInherit = ""); + template + FFPython& regFunc(T func, const std::string& name) { + return reg(new ScriptFuncImpl(func), name, E_STATIC_FUNC); + } + template + FFPython& regClass(const std::string& nameClass, std::string nameInherit = "") { + ScriptCppOps::ClassTypeReal*>::BindClassName = nameClass; + return reg(new ScriptClassImpl(), nameClass, E_CLASS_NEW, nameClass, nameInherit); + } + template + FFPython& regMethod(T func, const std::string& name, std::string nameClass = "") { + return reg(new ScriptMethodImpl(func), name, E_CLASS_METHOD, nameClass); + } + template + FFPython& regField(T func, const std::string& name) { + return reg(new ScriptFieldImpl(func), name, E_CLASS_FIELD); + } + + PyObject* callFuncByObj(PyObject* pFunc, std::vector& objArgs); + PyObject* callFunc(const std::string& modName, const std::string& funcName, std::vector& objArgs); + template + bool callFuncByObj(PyObject* pFunc, std::vector& objArgs, RET* pRet) + { + ScriptObjRefGuard retObj(CheckType::IsScriptObject(), callFuncByObj(pFunc, objArgs)); + if (pRet) { + *pRet = ScriptCppOps::scriptToCpp(retObj.value, *pRet); + } + return getErrMsg().empty(); + } + template + RET_V callFuncByObjRet(PyObject* pFunc, std::vector& objArgs) + { + RET_V ret = InitValueTrait::value(); + callFuncByObj(pFunc, objArgs, &ret); + return getErrMsg().empty(); + } + template + RET_V callMethodByObjRet(PyObject* pObj, const std::string& nameFunc, std::vector& objArgs) + { + PyObject* pFunc = PyObject_GetAttrString(pObj, nameFunc.c_str()); + if (!pFunc) { + Py_RETURN_NONE; + } + RET_V ret = InitValueTrait::value(); + callFuncByObj(pFunc, objArgs, &ret); + Py_XDECREF(pFunc); + return getErrMsg().empty(); + } + template + bool callFunc(const std::string& modName, const std::string& funcName, std::vector& objArgs, RET* pRet) + { + ScriptObjRefGuard retObj(CheckType::IsScriptObject(), callFunc(modName, funcName, objArgs)); + if (pRet) { + *pRet = ScriptCppOps::scriptToCpp(retObj.value, *pRet); + } + return getErrMsg().empty(); + } + //! python֧9 + template + RET_V call(const std::string& modName, const std::string& funcName + ) + { + RET_V ret = InitValueTrait::value(); + std::vector& args = allocArgList(); + + ScriptObjRefGuard retObj(CheckType::IsScriptObject(), callFunc(modName, funcName, args)); + ScriptCppOps::scriptToCpp(retObj.value, ret); + return ret; + } + template + RET_V call(const std::string& modName, const std::string& funcName + , const ARG1& arg1) + { + RET_V ret = InitValueTrait::value(); + std::vector& args = allocArgList(); + args.push_back(ScriptCppOps::scriptFromCpp(arg1)); + + ScriptObjRefGuard retObj(CheckType::IsScriptObject(), callFunc(modName, funcName, args)); + ScriptCppOps::scriptToCpp(retObj.value, ret); + return ret; + } + template + RET_V call(const std::string& modName, const std::string& funcName + , const ARG1& arg1, const ARG2& arg2) + { + RET_V ret = InitValueTrait::value(); + std::vector& args = allocArgList(); + args.push_back(ScriptCppOps::scriptFromCpp(arg1)); + args.push_back(ScriptCppOps::scriptFromCpp(arg2)); + + ScriptObjRefGuard retObj(CheckType::IsScriptObject(), callFunc(modName, funcName, args)); + ScriptCppOps::scriptToCpp(retObj.value, ret); + return ret; + } + template + RET_V call(const std::string& modName, const std::string& funcName + , const ARG1& arg1, const ARG2& arg2, const ARG3& arg3) + { + RET_V ret = InitValueTrait::value(); + std::vector& args = allocArgList(); + args.push_back(ScriptCppOps::scriptFromCpp(arg1)); + args.push_back(ScriptCppOps::scriptFromCpp(arg2)); + args.push_back(ScriptCppOps::scriptFromCpp(arg3)); + + ScriptObjRefGuard retObj(CheckType::IsScriptObject(), callFunc(modName, funcName, args)); + ScriptCppOps::scriptToCpp(retObj.value, ret); + return ret; + } + template + RET_V call(const std::string& modName, const std::string& funcName + , const ARG1& arg1, const ARG2& arg2, const ARG3& arg3, const ARG4& arg4) + { + RET_V ret = InitValueTrait::value(); + std::vector& args = allocArgList(); + args.push_back(ScriptCppOps::scriptFromCpp(arg1)); + args.push_back(ScriptCppOps::scriptFromCpp(arg2)); + args.push_back(ScriptCppOps::scriptFromCpp(arg3)); + args.push_back(ScriptCppOps::scriptFromCpp(arg4)); + + ScriptObjRefGuard retObj(CheckType::IsScriptObject(), callFunc(modName, funcName, args)); + ScriptCppOps::scriptToCpp(retObj.value, ret); + return ret; + } + template + RET_V call(const std::string& modName, const std::string& funcName + , const ARG1& arg1, const ARG2& arg2, const ARG3& arg3, const ARG4& arg4 + , const ARG5& arg5) + { + RET_V ret = InitValueTrait::value(); + std::vector& args = allocArgList(); + args.push_back(ScriptCppOps::scriptFromCpp(arg1)); + args.push_back(ScriptCppOps::scriptFromCpp(arg2)); + args.push_back(ScriptCppOps::scriptFromCpp(arg3)); + args.push_back(ScriptCppOps::scriptFromCpp(arg4)); + args.push_back(ScriptCppOps::scriptFromCpp(arg5)); + + ScriptObjRefGuard retObj(CheckType::IsScriptObject(), callFunc(modName, funcName, args)); + ScriptCppOps::scriptToCpp(retObj.value, ret); + return ret; + } + template + RET_V call(const std::string& modName, const std::string& funcName + , const ARG1& arg1, const ARG2& arg2, const ARG3& arg3, const ARG4& arg4 + , const ARG5& arg5, const ARG6& arg6) + { + RET_V ret = InitValueTrait::value(); + std::vector& args = allocArgList(); + args.push_back(ScriptCppOps::scriptFromCpp(arg1)); + args.push_back(ScriptCppOps::scriptFromCpp(arg2)); + args.push_back(ScriptCppOps::scriptFromCpp(arg3)); + args.push_back(ScriptCppOps::scriptFromCpp(arg4)); + args.push_back(ScriptCppOps::scriptFromCpp(arg5)); + args.push_back(ScriptCppOps::scriptFromCpp(arg6)); + + ScriptObjRefGuard retObj(CheckType::IsScriptObject(), callFunc(modName, funcName, args)); + ScriptCppOps::scriptToCpp(retObj.value, ret); + return ret; + } + template + RET_V call(const std::string& modName, const std::string& funcName + , const ARG1& arg1, const ARG2& arg2, const ARG3& arg3, const ARG4& arg4 + , const ARG5& arg5, const ARG6& arg6, const ARG7& arg7) + { + RET_V ret = InitValueTrait::value(); + std::vector& args = allocArgList(); + args.push_back(ScriptCppOps::scriptFromCpp(arg1)); + args.push_back(ScriptCppOps::scriptFromCpp(arg2)); + args.push_back(ScriptCppOps::scriptFromCpp(arg3)); + args.push_back(ScriptCppOps::scriptFromCpp(arg4)); + args.push_back(ScriptCppOps::scriptFromCpp(arg5)); + args.push_back(ScriptCppOps::scriptFromCpp(arg6)); + args.push_back(ScriptCppOps::scriptFromCpp(arg7)); + + ScriptObjRefGuard retObj(CheckType::IsScriptObject(), callFunc(modName, funcName, args)); + ScriptCppOps::scriptToCpp(retObj.value, ret); + return ret; + } + template + RET_V call(const std::string& modName, const std::string& funcName + , const ARG1& arg1, const ARG2& arg2, const ARG3& arg3, const ARG4& arg4 + , const ARG5& arg5, const ARG6& arg6, const ARG7& arg7, const ARG8& arg8) + { + RET_V ret = InitValueTrait::value(); + std::vector& args = allocArgList(); + args.push_back(ScriptCppOps::scriptFromCpp(arg1)); + args.push_back(ScriptCppOps::scriptFromCpp(arg2)); + args.push_back(ScriptCppOps::scriptFromCpp(arg3)); + args.push_back(ScriptCppOps::scriptFromCpp(arg4)); + args.push_back(ScriptCppOps::scriptFromCpp(arg5)); + args.push_back(ScriptCppOps::scriptFromCpp(arg6)); + args.push_back(ScriptCppOps::scriptFromCpp(arg7)); + args.push_back(ScriptCppOps::scriptFromCpp(arg8)); + + ScriptObjRefGuard retObj(CheckType::IsScriptObject(), callFunc(modName, funcName, args)); + ScriptCppOps::scriptToCpp(retObj.value, ret); + return ret; + } + template + RET_V call(const std::string& modName, const std::string& funcName + , const ARG1& arg1, const ARG2& arg2, const ARG3& arg3, const ARG4& arg4 + , const ARG5& arg5, const ARG6& arg6, const ARG7& arg7, const ARG8& arg8, const ARG9& arg9) + { + RET_V ret = InitValueTrait::value(); + std::vector& args = allocArgList(); + args.push_back(ScriptCppOps::scriptFromCpp(arg1)); + args.push_back(ScriptCppOps::scriptFromCpp(arg2)); + args.push_back(ScriptCppOps::scriptFromCpp(arg3)); + args.push_back(ScriptCppOps::scriptFromCpp(arg4)); + args.push_back(ScriptCppOps::scriptFromCpp(arg5)); + args.push_back(ScriptCppOps::scriptFromCpp(arg6)); + args.push_back(ScriptCppOps::scriptFromCpp(arg7)); + args.push_back(ScriptCppOps::scriptFromCpp(arg8)); + args.push_back(ScriptCppOps::scriptFromCpp(arg9)); + + ScriptObjRefGuard retObj(CheckType::IsScriptObject(), callFunc(modName, funcName, args)); + ScriptCppOps::scriptToCpp(retObj.value, ret); + return ret; + } +public: + PyObject* getScriptVarByObj(PyObject* pyMod, const std::string& strVarName); + PyObject* getScriptVar(const std::string& strMod, const std::string& strVarName); + template + RET_V getVar(PyObject* pyMod, const std::string& strVarName) { + ScriptObjRefGuard retObj(CheckType::IsScriptObject(), getScriptVarByObj(pyMod, strVarName)); + RET_V ret = InitValueTrait::value(); + ScriptCppOps::scriptToCpp(retObj.value, ret); + return ret; + } + template + RET_V getVar(const std::string& strMod, const std::string& strVarName) { + ScriptObjRefGuard retObj(CheckType::IsScriptObject(), getScriptVar(strMod, strVarName)); + RET_V ret = InitValueTrait::value(); + ScriptCppOps::scriptToCpp(retObj.value, ret); + return ret; + } + template + bool setVar(const std::string& strMod, const std::string& strVarName, const T& val) + { + PyObject* pName = NULL, * pModule = NULL; + std::string err_msg; + + pName = PyString_FromString(strMod.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule){ + traceback(m_strErr); + return false; + } + + PyObject* pval = ScriptCppOps::scriptFromCpp(val);; + int ret = PyObject_SetAttrString(pModule, strVarName.c_str(), pval); + Py_DECREF(pModule); + return true; + } + const std::string& getErrMsg() { return m_strErr; } + std::vector& allocArgList() { m_listArgs.clear(); return m_listArgs; } + static ScriptIterface* getRegFuncByID(size_t i) { + if (i < m_regFuncs.size()) { + return m_regFuncs[i]; + } + return NULL; + } + int traceback(std::string& ret_); +private: + std::string m_strErr; + std::vector m_listArgs; + static std::vector m_regFuncs; + std::string m_curRegClassName; +public: + static std::map m_allocObjs; + static PyObject* pyobjBuildTmpObj; +}; +template<> +struct ScriptCppOps { + static PyObject* scriptFromCpp(int8_t n) { return PyLong_FromLong(long(n)); } + static bool scriptToCpp(PyObject* pvalue, int8_t& ret) { + if (PyLong_Check(pvalue)) { ret = (int8_t)PyLong_AsLong(pvalue); } + else if (PyBool_Check(pvalue)) { ret = (Py_False == pvalue ? 0 : 1); } + else if (PyFloat_Check(pvalue)) { ret = (int8_t)PyFloat_AsDouble(pvalue); } + else if (PyString_Check(pvalue)) { ret = (int8_t)atol(PyString_AsString(pvalue)); } + else { ret = 0; return false; } + return true; + } +}; +template<> +struct ScriptCppOps { + static PyObject* scriptFromCpp(uint8_t n) { return PyLong_FromLong(long(n)); } + static bool scriptToCpp(PyObject* pvalue, uint8_t& ret) { + if (PyLong_Check(pvalue)) { ret = (uint8_t)PyLong_AsLong(pvalue); } + else if (PyBool_Check(pvalue)) { ret = (Py_False == pvalue ? 0 : 1); } + else if (PyFloat_Check(pvalue)) { ret = (uint8_t)PyFloat_AsDouble(pvalue); } + else if (PyString_Check(pvalue)) { ret = (uint8_t)atol(PyString_AsString(pvalue)); } + else { ret = 0; return false; } + return true; + } +}; +template<> +struct ScriptCppOps { + static PyObject* scriptFromCpp(int16_t n) { return PyLong_FromLong(long(n)); } + static bool scriptToCpp(PyObject* pvalue, int16_t& ret) { + if (PyLong_Check(pvalue)) { ret = (int16_t)PyLong_AsLong(pvalue); } + else if (PyBool_Check(pvalue)) { ret = (Py_False == pvalue ? 0 : 1); } + else if (PyFloat_Check(pvalue)) { ret = (int16_t)PyFloat_AsDouble(pvalue); } + else if (PyString_Check(pvalue)) { ret = (int16_t)atol(PyString_AsString(pvalue)); } + else { ret = 0; return false; } + return true; + } +}; +template<> +struct ScriptCppOps { + static PyObject* scriptFromCpp(uint16_t n) { return PyLong_FromLong(long(n)); } + static bool scriptToCpp(PyObject* pvalue, uint16_t& ret) { + if (PyLong_Check(pvalue)) { ret = (uint16_t)PyLong_AsLong(pvalue); } + else if (PyBool_Check(pvalue)) { ret = (Py_False == pvalue ? 0 : 1); } + else if (PyFloat_Check(pvalue)) { ret = (uint16_t)PyFloat_AsDouble(pvalue); } + else if (PyString_Check(pvalue)) { ret = (uint16_t)atol(PyString_AsString(pvalue)); } + else { ret = 0; return false; } + return true; + } +}; +template<> +struct ScriptCppOps { + static PyObject* scriptFromCpp(int32_t n) { return PyLong_FromLong(long(n)); } + static bool scriptToCpp(PyObject* pvalue, int32_t& ret) { + if (PyLong_Check(pvalue)) { ret = (int32_t)PyLong_AsLong(pvalue); } + else if (PyBool_Check(pvalue)) { ret = (Py_False == pvalue ? 0 : 1); } + else if (PyFloat_Check(pvalue)) { ret = (int32_t)PyFloat_AsDouble(pvalue); } + else if (PyString_Check(pvalue)) { ret = (int32_t)atol(PyString_AsString(pvalue)); } + else { ret = 0; return false; } + return true; + } +}; +template<> +struct ScriptCppOps { + static PyObject* scriptFromCpp(uint32_t n) { return PyLong_FromLong(long(n)); } + static bool scriptToCpp(PyObject* pvalue, uint32_t& ret) { + if (PyLong_Check(pvalue)) { ret = (uint32_t)PyLong_AsLong(pvalue); } + else if (PyBool_Check(pvalue)) { ret = (Py_False == pvalue ? 0 : 1); } + else if (PyFloat_Check(pvalue)) { ret = (uint32_t)PyFloat_AsDouble(pvalue); } + else if (PyString_Check(pvalue)) { ret = (uint32_t)atol(PyString_AsString(pvalue)); } + else { ret = 0; return false; } + return true; + } +}; +template<> +struct ScriptCppOps { + static PyObject* scriptFromCpp(int64_t n) { return PyLong_FromLongLong(n); } + static bool scriptToCpp(PyObject* pvalue, int64_t& ret) { + if (PyLong_Check(pvalue)) { ret = (int64_t)PyLong_AsLongLong(pvalue); } + else if (PyBool_Check(pvalue)) { ret = (Py_False == pvalue ? 0 : 1); } + else if (PyFloat_Check(pvalue)) { ret = (int64_t)PyFloat_AsDouble(pvalue); } + else if (PyString_Check(pvalue)) { ret = (int64_t)atol(PyString_AsString(pvalue)); } + else { ret = 0; return false; } + return true; + } +}; +template<> +struct ScriptCppOps { + static PyObject* scriptFromCpp(uint64_t n) { return PyLong_FromLongLong(long(n)); } + static bool scriptToCpp(PyObject* pvalue, uint64_t& ret) { + if (PyLong_Check(pvalue)) { ret = (uint64_t)PyLong_AsLongLong(pvalue); } + else if (PyBool_Check(pvalue)) { ret = (Py_False == pvalue ? 0 : 1); } + else if (PyFloat_Check(pvalue)) { ret = (uint64_t)PyFloat_AsDouble(pvalue); } + else if (PyString_Check(pvalue)) { ret = (uint64_t)atol(PyString_AsString(pvalue)); } + else { ret = 0; return false; } + return true; + } +}; +template<> struct ScriptCppOps { + static PyObject* scriptFromCpp(float n) { return PyFloat_FromDouble(float(n)); } + static bool scriptToCpp(PyObject* pvalue, float& ret) { + if (PyLong_Check(pvalue)) { ret = (float)PyLong_AsLong(pvalue); } + else if (PyFloat_Check(pvalue)) { ret = (float)PyFloat_AsDouble(pvalue); } + else if (PyString_Check(pvalue)) { ret = (float)atof(PyString_AsString(pvalue)); } + else { ret = 0.0; return false; } + return true; + } +}; +template<> struct ScriptCppOps { + static PyObject* scriptFromCpp(double n) { return PyFloat_FromDouble(double(n)); } + static bool scriptToCpp(PyObject* pvalue, double& ret) { + if (PyLong_Check(pvalue)) { ret = (double)PyLong_AsLong(pvalue); } + else if (PyFloat_Check(pvalue)) { ret = (double)PyFloat_AsDouble(pvalue); } + else if (PyString_Check(pvalue)) { ret = (double)atof(PyString_AsString(pvalue)); } + else { ret = 0.0; return false; } + return true; + } +}; +template<> struct ScriptCppOps { + static PyObject* scriptFromCpp(bool n) { if (n) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } + static bool scriptToCpp(PyObject* pvalue, bool& ret) { + if (Py_False == pvalue || Py_None == pvalue) { ret = false; } + else { ret = true; } + return true; + } +}; +template<> struct ScriptCppOps { + static PyObject* scriptFromCpp(const std::string& n) { return PyUnicode_FromStringAndSize(n.c_str(), n.size()); } + static bool scriptToCpp(PyObject* pvalue, std::string& ret) { + if (PyLong_Check(pvalue)) { + char buff[64] = { 0 }; + SAFE_SPRINTF(buff, sizeof(buff), "%ld", PyLong_AsLong(pvalue)); + ret = buff; + } + else if (PyFloat_Check(pvalue)) { + char buff[64] = { 0 }; + SAFE_SPRINTF(buff, sizeof(buff), "%g", PyFloat_AsDouble(pvalue)); + ret = buff; + } + else if (PyString_Check(pvalue)) { + Py_ssize_t size = 0; +#ifdef PYTHON_3 + const char* pstr = NULL; +#else + char* pstr = NULL; +#endif + PyString_AsStringAndSize(pvalue, (&pstr), &size); + if (pstr) + ret.assign(pstr, size); + } + else { ret.clear(); return false; } + return true; + } +}; +template<> struct ScriptCppOps { + static PyObject* scriptFromCpp(const char* n) { return PyUnicode_FromString(n); } + static bool scriptToCpp(PyObject* pvalue, const char*& ret) { + if (PyString_Check(pvalue)) { + ret = PyString_AsString(pvalue); + } + else { ret = ""; return false; } + return true; + } +}; +template<> struct ScriptCppOps { + static PyObject* scriptFromCpp(void* n) { return PyLong_FromVoidPtr(n); } + static bool scriptToCpp(PyObject* pvalue, void*& ret) { + ret = PyLong_AsVoidPtr(pvalue); + return true; + } +}; +template struct ScriptCppOps { + static PyObject* scriptFromCpp(const char* n) { return PyUnicode_FromString(n); } +}; +template<> struct ScriptCppOps { + static PyObject* scriptFromCpp(PyObject* n) { return n; } + static bool scriptToCpp(PyObject* pvalue, PyObject*& ret) { + ret = pvalue; + return true; + } +}; +template struct ScriptCppOps { + static std::string BindClassName; + static PyObject* scriptFromCpp(T* n) { + if (!FFPython::pyobjBuildTmpObj) { + Py_RETURN_NONE; + } + PyObject* pFunc = FFPython::pyobjBuildTmpObj; + PyObject* pValue = NULL; + if (pFunc && PyCallable_Check(pFunc)) { + PyObject* pArgs = PyTuple_New(2); + PyTuple_SetItem(pArgs, 0, ScriptCppOps::scriptFromCpp(BindClassName)); + PyTuple_SetItem(pArgs, 1, PyLong_FromVoidPtr(n)); + pValue = PyObject_CallObject(pFunc, pArgs); + Py_DECREF(pArgs); + } + if (!pValue) { + PyErr_Print(); + Py_RETURN_NONE; + } + return pValue; + } + static bool scriptToCpp(PyObject* pyobjVal, T*& ret) { + PyObject* pValue = PyObject_GetAttrString(pyobjVal, "_cppInterObj_"); + if (pValue) { + ret = (T*)PyLong_AsVoidPtr(pValue); + Py_DECREF(pValue); + } + return true; + } +}; +template std::string ScriptCppOps::BindClassName; +template +struct ScriptCppOps > +{ + static PyObject* scriptFromCpp(const std::vector& argVal) + { + PyObject* ret = PyList_New(argVal.size()); + for (size_t i = 0; i < argVal.size(); ++i) + { + PyList_SetItem(ret, i, ScriptCppOps::scriptFromCpp(argVal[i])); + } + return ret; + } + static bool scriptToCpp(PyObject* pyobjVal, std::vector& retVal) + { + retVal.clear(); + if (true == PyTuple_Check(pyobjVal)) + { + Py_ssize_t n = PyTuple_Size(pyobjVal); + for (Py_ssize_t i = 0; i < n; ++i) + { + retVal.push_back(T()); + ScriptCppOps::scriptToCpp(PyTuple_GetItem(pyobjVal, i), retVal.back()); + } + } + else if (true == PyList_Check(pyobjVal)) + { + Py_ssize_t n = PyList_Size(pyobjVal); + for (Py_ssize_t i = 0; i < n; ++i) + { + retVal.push_back(T()); + ScriptCppOps::scriptToCpp(PyList_GetItem(pyobjVal, i), retVal.back()); + } + } + else + return false; + return true; + } +}; +template +struct ScriptCppOps > +{ + static PyObject* scriptFromCpp(const std::list& argVal) + { + PyObject* ret = PyList_New(argVal.size()); + int i = 0; + for (typename std::list::const_iterator it = argVal.begin(); it != argVal.end(); ++it) + { + PyList_SetItem(ret, i++, ScriptCppOps::scriptFromCpp(*it)); + } + return ret; + } + static bool scriptToCpp(PyObject* pyobjVal, std::list& retVal) + { + retVal.clear(); + if (true == PyTuple_Check(pyobjVal)) + { + Py_ssize_t n = PyTuple_Size(pyobjVal); + for (Py_ssize_t i = 0; i < n; ++i) + { + retVal.push_back(T()); + ScriptCppOps::scriptToCpp(PyTuple_GetItem(pyobjVal, i), retVal.back()); + } + } + else if (true == PyList_Check(pyobjVal)) + { + Py_ssize_t n = PyList_Size(pyobjVal); + for (Py_ssize_t i = 0; i < n; ++i) + { + retVal.push_back(T()); + ScriptCppOps::scriptToCpp(PyList_GetItem(pyobjVal, i), retVal.back()); + } + } + else + return false; + return true; + } +}; +template +struct ScriptCppOps > +{ + static PyObject* scriptFromCpp(const std::set& argVal) + { + PyObject* ret = PySet_New(NULL); + for (typename std::set::const_iterator it = argVal.begin(); it != argVal.end(); ++it) + { + PyObject* v = ScriptCppOps::scriptFromCpp(*it); + PySet_Add(ret, v); + Py_DECREF(v); + } + return ret; + } + static bool scriptToCpp(PyObject* pyobjVal, std::set& retVal) + { + retVal.clear(); + PyObject* iter = PyObject_GetIter(pyobjVal); + PyObject* item = NULL; + while (NULL != iter && NULL != (item = PyIter_Next(iter))) + { + T tmp(); + if (ScriptCppOps::scriptToCpp(item, tmp)) + { + Py_DECREF(item); + Py_DECREF(iter); + return false; + } + retVal.insert(tmp); + Py_DECREF(item); + } + if (iter) + { + Py_DECREF(iter); + } + return true; + } +}; +template +struct ScriptCppOps > +{ + static PyObject* scriptFromCpp(const std::map& argVal) + { + PyObject* ret = PyDict_New(); + for (typename std::map::const_iterator it = argVal.begin(); it != argVal.end(); ++it) + { + PyObject* k = ScriptCppOps::scriptFromCpp(it->first); + PyObject* v = ScriptCppOps::scriptFromCpp(it->second); + PyDict_SetItem(ret, k, v); + Py_DECREF(k); + Py_DECREF(v); + } + return ret; + } + static bool scriptToCpp(PyObject* pyobjVal, std::map& retVal) + { + retVal.clear(); + if (true == PyDict_Check(pyobjVal)) + { + PyObject* key = NULL, * value = NULL; + Py_ssize_t pos = 0; + + while (PyDict_Next(pyobjVal, &pos, &key, &value)) + { + T arg1 = InitValueTrait::value(); + R arg2 = InitValueTrait::value(); + ScriptCppOps::scriptToCpp(key, arg1); + ScriptCppOps::scriptToCpp(value, arg2); + retVal[arg1] = arg2; + } + } + return true; + } +}; +template struct RefTypeTraits { typedef T RealType; }; +template struct RefTypeTraits { typedef T RealType; }; +template struct RefTypeTraits { typedef T RealType; }; +template struct RefTypeTraits { typedef T RealType; }; +//!ֵʼ +template +class ScriptFuncImpl : public ScriptIterface { +public: + typedef RET(*FuncType)(); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(0), func(f) {} + virtual PyObject* handleRun() { + return ScriptCppOps::scriptFromCpp(func()); + } +}; +template +class ScriptFuncImpl : public ScriptIterface { +public: + typedef RET(*FuncType)(ARG1); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(1), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + return ScriptCppOps::scriptFromCpp(func(arg1)); + } +}; +template +class ScriptFuncImpl : public ScriptIterface { +public: + typedef RET(*FuncType)(ARG1, ARG2); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(2), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + return ScriptCppOps::scriptFromCpp(func(arg1, arg2)); + } +}; +template +class ScriptFuncImpl : public ScriptIterface { +public: + typedef RET(*FuncType)(ARG1, ARG2, ARG3); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(3), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + return ScriptCppOps::scriptFromCpp(func(arg1, arg2, arg3)); + } +}; +template +class ScriptFuncImpl : public ScriptIterface { +public: + typedef RET(*FuncType)(ARG1, ARG2, ARG3, ARG4); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(4), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + return ScriptCppOps::scriptFromCpp(func(arg1, arg2, arg3, arg4)); + } +}; +template +class ScriptFuncImpl : public ScriptIterface { +public: + typedef RET(*FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(5), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + return ScriptCppOps::scriptFromCpp(func(arg1, arg2, arg3, arg4, arg5)); + } +}; +template +class ScriptFuncImpl : public ScriptIterface { +public: + typedef RET(*FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(6), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + return ScriptCppOps::scriptFromCpp(func(arg1, arg2, arg3, arg4, arg5, arg6)); + } +}; +template +class ScriptFuncImpl : public ScriptIterface { +public: + typedef RET(*FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(7), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + return ScriptCppOps::scriptFromCpp(func(arg1, arg2, arg3, arg4, arg5, arg6, arg7)); + } +}; +template +class ScriptFuncImpl : public ScriptIterface { +public: + typedef RET(*FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(8), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + return ScriptCppOps::scriptFromCpp(func(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)); + } +}; +template +class ScriptFuncImpl : public ScriptIterface { +public: + typedef RET(*FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(9), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg9 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + ScriptCppOps::RealType>::scriptToCpp(arg(9), arg9); + return ScriptCppOps::scriptFromCpp(func(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)); + } +}; +//!ֵ +//!voidʼ +template <> +class ScriptFuncImpl : public ScriptIterface{ +public: + typedef void(*FuncType)(); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(0), func(f) {} + virtual PyObject* handleRun() { + func(); + Py_RETURN_NONE; + } +}; +template < typename ARG1> +class ScriptFuncImpl : public ScriptIterface{ +public: + typedef void(*FuncType)(ARG1); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(1), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + func(arg1); + Py_RETURN_NONE; + } +}; +template < typename ARG1, typename ARG2> +class ScriptFuncImpl : public ScriptIterface{ +public: + typedef void(*FuncType)(ARG1,ARG2); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(2), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + func(arg1,arg2); + Py_RETURN_NONE; + } +}; +template < typename ARG1, typename ARG2, typename ARG3> +class ScriptFuncImpl : public ScriptIterface{ +public: + typedef void(*FuncType)(ARG1,ARG2,ARG3); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(3), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + func(arg1,arg2,arg3); + Py_RETURN_NONE; + } +}; +template < typename ARG1, typename ARG2, typename ARG3, typename ARG4> +class ScriptFuncImpl : public ScriptIterface{ +public: + typedef void(*FuncType)(ARG1,ARG2,ARG3,ARG4); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(4), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + func(arg1,arg2,arg3,arg4); + Py_RETURN_NONE; + } +}; +template < typename ARG1, typename ARG2, typename ARG3, typename ARG4 + , typename ARG5> +class ScriptFuncImpl : public ScriptIterface{ +public: + typedef void(*FuncType)(ARG1,ARG2,ARG3,ARG4,ARG5); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(5), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + func(arg1,arg2,arg3,arg4,arg5); + Py_RETURN_NONE; + } +}; +template < typename ARG1, typename ARG2, typename ARG3, typename ARG4 + , typename ARG5, typename ARG6> +class ScriptFuncImpl : public ScriptIterface{ +public: + typedef void(*FuncType)(ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(6), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + func(arg1,arg2,arg3,arg4,arg5,arg6); + Py_RETURN_NONE; + } +}; +template < typename ARG1, typename ARG2, typename ARG3, typename ARG4 + , typename ARG5, typename ARG6, typename ARG7> +class ScriptFuncImpl : public ScriptIterface{ +public: + typedef void(*FuncType)(ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(7), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + func(arg1,arg2,arg3,arg4,arg5,arg6,arg7); + Py_RETURN_NONE; + } +}; +template < typename ARG1, typename ARG2, typename ARG3, typename ARG4 + , typename ARG5, typename ARG6, typename ARG7, typename ARG8> +class ScriptFuncImpl : public ScriptIterface{ +public: + typedef void(*FuncType)(ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(8), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + func(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8); + Py_RETURN_NONE; + } +}; +template < typename ARG1, typename ARG2, typename ARG3, typename ARG4 + , typename ARG5, typename ARG6, typename ARG7, typename ARG8, typename ARG9> +class ScriptFuncImpl : public ScriptIterface{ +public: + typedef void(*FuncType)(ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8,ARG9); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(9), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg9 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + ScriptCppOps::RealType>::scriptToCpp(arg(9), arg9); + func(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9); + Py_RETURN_NONE; + } +}; +//!void 캯 +//!캯 +template +class ScriptClassImpl :public ScriptIterface +{ +public: + typedef CLASS_TYPE ClassTypeReal; + ScriptClassImpl() :ScriptIterface(0) {} + virtual void* handleNew() { + return new CLASS_TYPE(); + } + virtual void handleDel() { + delete (CLASS_TYPE*)(this->pobjArg); + } +}; +template +class ScriptClassImpl :public ScriptIterface +{ +public: + typedef CLASS_TYPE ClassTypeReal; + ScriptClassImpl() :ScriptIterface(1) {} + virtual void* handleNew() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + return new CLASS_TYPE(arg1); + } + virtual void handleDel() { + delete (CLASS_TYPE*)(this->pobjArg); + } +}; +template +class ScriptClassImpl :public ScriptIterface +{ +public: + typedef CLASS_TYPE ClassTypeReal; + ScriptClassImpl() :ScriptIterface(2) {} + virtual void* handleNew() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + return new CLASS_TYPE(arg1, arg2); + } + virtual void handleDel() { + delete (CLASS_TYPE*)(this->pobjArg); + } +}; +template +class ScriptClassImpl :public ScriptIterface +{ +public: + typedef CLASS_TYPE ClassTypeReal; + ScriptClassImpl() :ScriptIterface(3) {} + virtual void* handleNew() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + return new CLASS_TYPE(arg1, arg2, arg3); + } + virtual void handleDel() { + delete (CLASS_TYPE*)(this->pobjArg); + } +}; +template +class ScriptClassImpl :public ScriptIterface +{ +public: + typedef CLASS_TYPE ClassTypeReal; + ScriptClassImpl() :ScriptIterface(4) {} + virtual void* handleNew() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + return new CLASS_TYPE(arg1, arg2, arg3, arg4); + } + virtual void handleDel() { + delete (CLASS_TYPE*)(this->pobjArg); + } +}; +template + class ScriptClassImpl :public ScriptIterface +{ +public: + typedef CLASS_TYPE ClassTypeReal; + ScriptClassImpl() :ScriptIterface(5) {} + virtual void* handleNew() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + return new CLASS_TYPE(arg1, arg2, arg3, arg4, arg5); + } + virtual void handleDel() { + delete (CLASS_TYPE*)(this->pobjArg); + } +}; +template + class ScriptClassImpl :public ScriptIterface +{ +public: + typedef CLASS_TYPE ClassTypeReal; + ScriptClassImpl() :ScriptIterface(6) {} + virtual void* handleNew() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + return new CLASS_TYPE(arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual void handleDel() { + delete (CLASS_TYPE*)(this->pobjArg); + } +}; +template + class ScriptClassImpl :public ScriptIterface +{ +public: + typedef CLASS_TYPE ClassTypeReal; + ScriptClassImpl() :ScriptIterface(7) {} + virtual void* handleNew() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + return new CLASS_TYPE(arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual void handleDel() { + delete (CLASS_TYPE*)(this->pobjArg); + } +}; +template + class ScriptClassImpl :public ScriptIterface +{ +public: + typedef CLASS_TYPE ClassTypeReal; + ScriptClassImpl() :ScriptIterface(8) {} + virtual void* handleNew() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + return new CLASS_TYPE(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual void handleDel() { + delete (CLASS_TYPE*)(this->pobjArg); + } +}; +template + class ScriptClassImpl :public ScriptIterface +{ +public: + typedef CLASS_TYPE ClassTypeReal; + ScriptClassImpl() :ScriptIterface(9) {} + virtual void* handleNew() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg9 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + ScriptCppOps::RealType>::scriptToCpp(arg(9), arg9); + return new CLASS_TYPE(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual void handleDel() { + delete (CLASS_TYPE*)(this->pobjArg); + } +}; +//!캯 +//!ֵ෽ʼ +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef RET(CLASS_TYPE::* FuncType)(); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(0), func(f) {} + virtual PyObject* handleRun() { + + return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)()); + } +}; +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef RET(CLASS_TYPE::* FuncType)(ARG1); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(1), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + + return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)(arg1)); + } +}; +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef RET(CLASS_TYPE::* FuncType)(ARG1, ARG2); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(2), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + + return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)(arg1, arg2)); + } +}; +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef RET(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(3), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + + return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3)); + } +}; +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef RET(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3, ARG4); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(4), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + + return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4)); + } +}; +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef RET(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(5), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + + return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5)); + } +}; +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef RET(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(6), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + + return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5, arg6)); + } +}; +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef RET(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(7), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + + return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5, arg6, arg7)); + } +}; +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef RET(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(8), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + + return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)); + } +}; +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef RET(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(9), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg9 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + ScriptCppOps::RealType>::scriptToCpp(arg(9), arg9); + + return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)); + } +}; +//!ֵ෽ +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef void(CLASS_TYPE::* FuncType)(); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(0), func(f) {} + virtual PyObject* handleRun() { + + ((CLASS_TYPE*)pobjArg->*func)(); + Py_RETURN_NONE; + } +}; +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef void(CLASS_TYPE::* FuncType)(ARG1); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(1), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + + ((CLASS_TYPE*)pobjArg->*func)(arg1); + Py_RETURN_NONE; + } +}; +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef void(CLASS_TYPE::* FuncType)(ARG1, ARG2); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(2), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + + ((CLASS_TYPE*)pobjArg->*func)(arg1, arg2); + Py_RETURN_NONE; + } +}; +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef void(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(3), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + + ((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3); + Py_RETURN_NONE; + } +}; +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef void(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3, ARG4); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(4), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + + ((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4); + Py_RETURN_NONE; + } +}; +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef void(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(5), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + + ((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5); + Py_RETURN_NONE; + } +}; +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef void(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(6), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + + ((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5, arg6); + Py_RETURN_NONE; + } +}; +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef void(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(7), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + + ((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5, arg6, arg7); + Py_RETURN_NONE; + } +}; +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef void(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(8), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + + ((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + Py_RETURN_NONE; + } +}; +template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef void(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(9), func(f) {} + virtual PyObject* handleRun() { + typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); + typename RefTypeTraits::RealType arg9 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + ScriptCppOps::RealType>::scriptToCpp(arg(9), arg9); + + ((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + Py_RETURN_NONE; + } +}; +//!void෽ +//!ֶοʼ +template +class ScriptFieldImpl : public ScriptIterface { +public: + typedef RET(CLASS_TYPE::* FieldType); FieldType field; + ScriptFieldImpl(FieldType f) :ScriptIterface(0), field(f) {} + virtual PyObject* handleRun() { + if (tmpArgs.empty()) //!]вȡֵвǸֵ + return ScriptCppOps::scriptFromCpp((CLASS_TYPE*)pobjArg->*field); + ScriptCppOps::scriptToCpp(arg(1), (CLASS_TYPE*)pobjArg->*field); + Py_RETURN_NONE; + } +}; +//!ֶν +}//end namespace ff +#endif // ! _FFPYTHON_H_ + + diff --git a/fftest.py b/fftest.py index 24e2f77..890f80f 100644 --- a/fftest.py +++ b/fftest.py @@ -1,79 +1,81 @@ - - -def test_base(a1, a2, a3): - print('test_base', a1, a2, a3) - return 0 - -def test_stl(a1, a2, a3): - print('test_stl', a1, a2, a3) - return True - -def test_return_stl(): - print('test_return_stl') - #map > > - ret = {'Oh':[[111,222], [333, 444] ] } - return ret - -def test_reg_function(): - import cppext - cppext.print_val(123, 45.6 , "----789---", [3.14]) - ret = cppext.return_stl() - print('test_reg_function', ret) - -def test_register_base_class(): - import cppext - foo = cppext.foo_t(20130426) - - print("test_register_base_class get_val:", foo.get_value()) - foo.set_value(778899) - print("test_register_base_class get_val:", foo.get_value(), foo.m_value) - foo.test_stl({"key": [11,22,33] }) - print('test_register_base_class test_register_base_class', foo) - -def test_register_inherit_class(): - import cppext - dumy = cppext.dumy_t(20130426) - print("test_register_inherit_class get_val:", dumy.get_value()) - dumy.set_value(778899) - print("test_register_inherit_class get_val:", dumy.get_value(), dumy.m_value) - dumy.test_stl({"key": [11,22,33] }) - dumy.dump() - print('test_register_inherit_class', dumy) - -def test_cpp_obj_to_py_ext(foo): - print('test_cpp_obj_to_py_ext', len(foo)) - for k in range(0, len(foo)): - print('test_cpp_obj_to_py_ext', k, foo[k].m_value) - -def test_cpp_obj_to_py(foo): - import cppext - print("test_cpp_obj_to_py get_val:", foo.get_value()) - foo.set_value(778899) - print("test_cpp_obj_to_py get_val:", foo.get_value(), foo.m_value) - foo.test_stl({"key": [11,22,33] }) - foo.m_value = 100 - print('test_cpp_obj_to_py test_register_base_class', foo) - -def test_cpp_obj_py_obj(dumy): - import cppext - print("test_cpp_obj_py_obj get_val:", dumy.get_value()) - dumy.set_value(778899) - print("test_cpp_obj_py_obj get_val:", dumy.get_value(), dumy.m_value) - dumy.test_stl({"key": [11,22,33] }) - dumy.dump() - cppext.obj_test(dumy) - print('test_cpp_obj_py_obj', dumy) - - return dumy - -class pyclass_t: - def __init__(self): - print('pyclass_t init....') - def sayHi(self, a1, a2): - print('sayHi..', a1, a2) -def test_cpp_obj_return_py_obj(): - return pyclass_t() -def test_cpp_obj_return_py_lambda(): - def test_lambda(a1): - print('test_lambda....', a1) - return test_lambda + + +def testBase(a1, a2, a3): + print('testBase', a1, a2, a3) + return 0 + +def testStl(a1, a2, a3): + print('testStl', a1, a2, a3) + return True + +def test_returnStl(): + print('test_returnStl') + #map > > + ret = {'Oh':[[111,222], [333, 444] ] } + return ret + +def testRegFunction(): + import ffpython + ffpython.printVal(123, 45.6 , "----789---", [3.14]) + ret = ffpython.returnStl() + print('testRegFunction', ret) + +def testRegisterBaseClass(): + import ffpython + foo = ffpython.Foo(20130426) + + print("testRegisterBaseClass get_val:", foo.getValue()) + foo.setValue(778899) + print("testRegisterBaseClass get_val:", foo.getValue(), foo.nValue) + foo.testStl({"key": [11,22,33] }) + print('testRegisterBaseClass testRegisterBaseClass', foo) + +def testRegisterInheritClass(): + import ffpython + dumy = ffpython.Dumy(20130426) + print("testRegisterInheritClass get_val:", dumy.getValue()) + dumy.setValue(778899) + print("testRegisterInheritClass get_val:", dumy.getValue(), dumy.nValue) + dumy.testStl({"key": [11,22,33] }) + dumy.dump() + print('testRegisterInheritClass', dumy) + +def testCppObjToPy_ext(foo): + print('testCppObjToPy_ext', len(foo)) + for k in range(0, len(foo)): + print('testCppObjToPy_ext', k, foo[k].nValue) + +def testCppObjToPy(foo): + import ffpython + print("testCppObjToPy get_val:", foo.getValue()) + foo.setValue(778899) + print("testCppObjToPy get_val:", foo.getValue(), foo.nValue) + foo.testStl({"key": [11,22,33] }) + foo.nValue = 100 + print('testCppObjToPy testRegisterBaseClass', foo) + +def testCppObjToPy2(dumyList): + dumy = dumyList[0] + import ffpython + print("testCppObjToPy get_val:", dumy.getValue()) + dumy.setValue(778899) + print("testCppObjToPy get_val:", dumy.getValue(), dumy.nValue) + dumy.testStl({"key": [11,22,33] }) + dumy.dump() + ffpython.objTest(dumy) + print('testCppObjToPy', dumy) + + return dumy + +class PyClass: + def __init__(self): + print('PyClass init....') + def sayHi(self, a1, a2): + print('sayHi..', a1, a2) +def testCppObjReturnPyObj(): + import ffpython + return PyClass() +def testCppObjReturnPyLambda(): + def testLambda(a1): + print('testLambda....', a1) + return testLambda diff --git a/gencode.py b/gencode.py new file mode 100644 index 0000000..4996869 --- /dev/null +++ b/gencode.py @@ -0,0 +1,221 @@ + +def gencode_pyops(): + template = '''template<> +struct ScriptCppOps{ + static PyObject* scriptFromCpp(int32_t n) { return PyLong_FromLong(long(n)); } + static bool scriptToCpp(PyObject* pvalue, int32_t& ret){ + if (PyLong_Check(pvalue)){ ret = (int32_t)PyLong_AsLong(pvalue); } + else if (PyBool_Check(pvalue)) { ret = (Py_False == pvalue?0:1); } + else if (PyFloat_Check(pvalue)) { ret = (int32_t)PyFloat_AsDouble(pvalue); } + else if (PyUnicode_Check(pvalue)) { ret = (int32_t)atol(PyUnicode_AsUTF8(pvalue)); } + else { ret = 0; return false; } + return true; + } +};''' + for k in ['int8_t', 'uint8_t', 'int16_t', 'uint16_t', 'int32_t', 'uint32_t', 'int64_t', 'uint64_t']: + code = template.replace('int32_t', k) + print(code) + +def gencode_call(): + + for m in range(10): + argtypename = '' + argtypelist = '' + arglist = '' + for i in range(m): + k = i+ 1 + if k == 5: + argtypename += '\n ' + argtypelist += '\n ' + + argtypename += ', typename ARG%d'%(k) + argtypelist += ', const ARG%d& arg%d'%(k, k) + arglist += ' args.push_back(ScriptCppOps::scriptFromCpp(arg%d));\n'%(k, k) + template = '''template +RET_V call(const std::string& modName, const std::string& funcName + %s) +{ + RET_V ret = InitValueTrait::value(); + std::vector& args = allocArgList(); +%s + PyObjRefGuard retObj(callFunc(modName, funcName, args)); + ScriptCppOps::scriptToCpp(retObj.value, ret); + return ret; +}'''%(argtypename, argtypelist, arglist) + code = template + print(code) +def gencode_ScriptFuncImpl(isVoid=False): + for m in range(10): + argtypename = '' + argtype2 = '' + argtypelist = '' + arglist = '' + arglowerlist = '' + for i in range(m): + k = i+ 1 + if k == 5: + argtypename += '\n ' + + argtypename += ', typename ARG%d'%(k) + if argtype2: + argtype2 += ',' + argtype2 += 'ARG%d'%(k) + argtypelist += ' typename RefTypeTraits::RealType arg%d = InitValueTrait::RealType>::value();\n'%(k, k, k) + arglist += ' ScriptCppOps::RealType>::scriptToCpp(arg(%d), arg%d);\n'%(k, k, k) + if arglowerlist: + arglowerlist += ',' + arglowerlist += 'arg%d'%(k) + retStr = 'return ScriptCppOps::scriptFromCpp(func(%s));'%(arglowerlist) + if isVoid: + retStr = 'func(%s);\n Py_RETURN_NONE;'%(arglowerlist); + template = '''template +class ScriptFuncImpl : public ScriptIterface{ +public: + typedef RET(*FuncType)(%s); FuncType func; + ScriptFuncImpl(FuncType f) :ScriptIterface(%d), func(f) {} + virtual PyObject* handleRun() { +%s%s + %s + } +};'''%(argtypename, argtype2, argtype2, m, argtypelist, arglist, retStr) + code = template + if isVoid: + code = code.replace('typename RET ,', '') + code = code.replace('typename RET ', '') + code = code.replace('RET(', 'void(') + print(code) + return +def genClassImpl(): + for m in range(10): + argtypename = '' + argtype2 = '' + argtypelist = '' + arglist = '' + arglowerlist = '' + for i in range(m): + k = i+ 1 + if k == 5: + argtypename += '\n ' + + argtypename += ', typename ARG%d'%(k) + if argtype2: + argtype2 += ',' + argtype2 += 'ARG%d'%(k) + argtypelist += ' typename RefTypeTraits::RealType arg%d = InitValueTrait::RealType>::value();\n'%(k, k, k) + arglist += ' ScriptCppOps::RealType>::scriptToCpp(arg(%d), arg%d);\n'%(k, k, k) + if arglowerlist: + arglowerlist += ',' + arglowerlist += 'arg%d'%(k) + retStr = 'return ScriptCppOps::scriptFromCpp(func(%s));'%(arglowerlist) + # if isVoid: + # retStr = 'func(%s);\n Py_RETURN_NONE;'%(arglowerlist); + template = '''template +class ScriptClassImpl :public ScriptIterface +{ +public: + typedef CLASS_TYPE ClassTypeReal; + ScriptClassImpl() :ScriptIterface(%d) {} + virtual void* handleNew() { +%s%s return new CLASS_TYPE(%s); + } + virtual void handleDel() { + delete (CLASS_TYPE*)(this->pobjArg); + } +};'''%(argtypename, argtype2, m, argtypelist, arglist, arglowerlist) + code = template + # if isVoid: + # code = code.replace('typename RET ,', '') + # code = code.replace('typename RET ', '') + # code = code.replace('RET(', 'void(') + print(code) +def MethodImpl(isVoid=False): + for m in range(10): + argtypename = '' + argtype2 = '' + argtypelist = '' + arglist = '' + arglowerlist = '' + for i in range(m): + k = i+ 1 + if k == 5 and False: + argtypename += '\n ' + + argtypename += ', typename ARG%d'%(k) + if argtype2: + argtype2 += ',' + argtype2 += 'ARG%d'%(k) + argtypelist += ' typename RefTypeTraits::RealType arg%d = InitValueTrait::RealType>::value();\n'%(k, k, k) + arglist += ' ScriptCppOps::RealType>::scriptToCpp(arg(%d), arg%d);\n'%(k, k, k) + if arglowerlist: + arglowerlist += ',' + arglowerlist += 'arg%d'%(k) + retStr = 'return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)(%s));'%(arglowerlist) + if isVoid: + retStr = '((CLASS_TYPE*)pobjArg->*func)(%s);\n Py_RETURN_NONE;'%(arglowerlist); + template = '''template +class ScriptMethodImpl : public ScriptIterface { +public: + typedef RET(CLASS_TYPE::*FuncType)(%s); FuncType func; + ScriptMethodImpl(FuncType f) :ScriptIterface(%d), func(f) {} + virtual PyObject* handleRun() { +%s%s + %s + } +};'''%(argtypename, argtype2, argtype2, m, argtypelist, arglist, retStr) + code = template + if isVoid: + code = code.replace('typename RET ,', '') + code = code.replace('typename RET ', '') + code = code.replace('RET(', 'void(') + code = code.replace('template ', 'template ') + print(code) + return +def foo(a= None): + import ffpython + #print('ffpython.callExt', ffpython.callExt(0, 0, [1])) + #print('ffpython.printVal', ffpython.printVal(22)) + #print('foo:%s'%(str(a))) + objMyExt = ffpython.MyExt(156) + print(objMyExt) + print('MyExt', objMyExt.add(20), objMyExt.testMethod(25), objMyExt.nNum) + objMyExt.nNum = 2099 + print('objMyExt.nNum', objMyExt.nNum) + + return '123' +if __name__ == '__main__': + #MethodImpl(True) + pass + +def GenField(className, fieldName, nFuncID): + classType = getattr(ffpython, className) + callExt = ffpython.callExt + def getFieldVal(self): + return callExt(self._cppInterObj_, nFuncID, (), 3) + def setFieldVal(self, value): + print('setVal', nFuncID, value) + return callExt(self._cppInterObj_, nFuncID, (value), 3) + setattr(classType, fieldName, property(getFieldVal, setFieldVal))#add property + return +class Base: + def __init__(self): + print('base init') + pass + def __del__(self): + print('Base del') +class Student(Base): + def __init__(self): + Base.__init__(self) + self._score = 100 + def __del__(self): + print('Student del') +# GenField(Student, 'score', 11) + +# s.score = 200 +# print('score', s.score) +# print(dir(Student)) +def buildTmpObj(className, ptr): + srcType = getattr(ffpython, className) + if srcType: + return srcType(cppTmpPtr=ptr) + return None + From 409a3d69d0689140bbffb4d26c44dd8d30e229ce Mon Sep 17 00:00:00 2001 From: fanchy Date: Wed, 17 Jun 2020 21:05:40 +0800 Subject: [PATCH 12/13] add new content --- README.md | 467 +++++++++++++++++++++++++++--------------------------- 1 file changed, 232 insertions(+), 235 deletions(-) diff --git a/README.md b/README.md index 75653cb..e24a399 100644 --- a/README.md +++ b/README.md @@ -1,235 +1,232 @@ -# ffpython -## default use python3 , python2 use files in python2.7 - -ffpython is a c++ lib,which is to simplify task that embed python and extend python. -For example, call python function, register c++ function to python, register c++ class to python. -Only one implement c++ header file. - -## Project Goals - * easier to embed python script - * easier to call python function - * easier to set or get var in python script - * easier to extend python with c++ static function - * easier to extend python with c++ class. C++ class Once registed, python can use it like builtin type. - * when python exception throw, ffpython will wrap it as a std exception which includes python traceback info. - -## Supported Python versions - * python2.5 python2.6 python2.7 python3, win / linux - - -## Embed Python script in C++ -### Get / Set varialbe in python script/module -``` c++ - printf("sys.version=%s\n", ffpython.get_global_var("sys", "version").c_str()); - ffpython.set_global_var("fftest", "global_var", "OhNice"); - printf("fftest.global_var=%s\n", ffpython.get_global_var("fftest", "global_var").c_str()); -``` -### call python function, Support all base type as arg or return value. Nine args can be supported. -``` c++ - int a1 = 100; float a2 = 3.14f; string a3 = "OhWell"; - ffpython.call("fftest", "test_base", a1, a2, a3); -``` -### call python function, Support all STL type as arg or return value. Nine args can be supported. Vector and List for tuple and list in python,map for dict in python. -``` c++ - vector a1;a1.push_back(100);a1.push_back(200); - list a2; a2.push_back("Oh");a2.push_back("Nice"); - vector > a3;a3.push_back(a2); - - ffpython.call("fftest", "test_stl", a1, a2, a3); - typedef map > > ret_t; - ret_t val = ffpython.call("fftest", "test_return_stl"); -``` - -### register c++ class, python can use it just like builtin types. -``` c++ - -class foo_t -{ -public: - foo_t(int v_):m_value(v_) - { - printf("%s\n", __FUNCTION__); - } - virtual ~foo_t() - { - printf("%s\n", __FUNCTION__); - } - int get_value() const { return m_value; } - void set_value(int v_) { m_value = v_; } - void test_stl(map >& v_) - { - printf("%s\n", __FUNCTION__); - } - int m_value; -}; - -class dumy_t: public foo_t -{ -public: - dumy_t(int v_):foo_t(v_) - { - printf("%s\n", __FUNCTION__); - } - ~dumy_t() - { - printf("%s\n", __FUNCTION__); - } - void dump() - { - printf("%s\n", __FUNCTION__); - } -}; - - -static foo_t* obj_test(dumy_t* p) -{ - printf("%s\n", __FUNCTION__); - return p; -} - - -``` -### Register c++ class which inherit a class having been registered. -``` c++ -ffpython.call("fftest", "test_register_inherit_class"); -``` -### C++ object pointer can be as a arg to python, and object can be access as a instance of builtin type in python. -``` c++ -void test_cpp_obj_to_py(ffpython_t& ffpython) -{ - foo_t tmp_foo(2013); - ffpython.call("fftest", "test_cpp_obj_to_py", &tmp_foo); -} -void test_cpp_obj_py_obj(ffpython_t& ffpython) -{ - dumy_t tmp_foo(2013); - - foo_t* p = ffpython.call("fftest", "test_cpp_obj_py_obj", &tmp_foo); -} -``` -## Extend Python -### register c++ static function, all base type supported. Arg num can be nine. -``` c++ -static int print_val(int a1, float a2, const string& a3, const vector& a4) -{ - printf("%s[%d,%f,%s,%d]\n", __FUNCTION__, a1, a2, a3.c_str(), a4.size()); - return 0; -} -struct ops_t -{ - static list return_stl() - { - list ret;ret.push_back(1024); - printf("%s\n", __FUNCTION__); - return ret; - } -}; - -std::string test_reg_function(ffpython_t& ffpython) -{ - ffpython.reg(&print_val, "print_val") - .reg(&ops_t::return_stl, "return_stl"); - - ffpython.reg_class("foo_t") - .reg(&foo_t::get_value, "get_value") - .reg(&foo_t::set_value, "set_value") - .reg(&foo_t::test_stl, "test_stl") - .reg_property(&foo_t::m_value, "m_value"); - - ffpython.reg_class("dumy_t", "dumy_t class inherit foo_t ctor ", "foo_t") - .reg(&dumy_t::dump, "dump"); - - ffpython.reg(obj_test, "obj_test"); - return "cppext"; -} - -``` -## Python test script -``` python - - -def test_base(a1, a2, a3): - print('test_base', a1, a2, a3) - return 0 - -def test_stl(a1, a2, a3): - print('test_stl', a1, a2, a3) - return True - -def test_return_stl(): - print('test_return_stl') - #map > > - ret = {'Oh':[[111,222], [333, 444] ] } - return ret - -def test_reg_function(): - import cppext - cppext.print_val(123, 45.6 , "----789---", [3.14]) - ret = cppext.return_stl() - print('test_reg_function', ret) - -def test_register_base_class(): - import cppext - foo = cppext.foo_t(20130426) - - print("test_register_base_class get_val:", foo.get_value()) - foo.set_value(778899) - print("test_register_base_class get_val:", foo.get_value(), foo.m_value) - foo.test_stl({"key": [11,22,33] }) - print('test_register_base_class test_register_base_class', foo) - -def test_register_inherit_class(): - import cppext - dumy = cppext.dumy_t(20130426) - print("test_register_inherit_class get_val:", dumy.get_value()) - dumy.set_value(778899) - print("test_register_inherit_class get_val:", dumy.get_value(), dumy.m_value) - dumy.test_stl({"key": [11,22,33] }) - dumy.dump() - print('test_register_inherit_class', dumy) - -def test_cpp_obj_to_py_ext(foo): - print('test_cpp_obj_to_py_ext', len(foo)) - for k in range(0, len(foo)): - print('test_cpp_obj_to_py_ext', k, foo[k].m_value) - -def test_cpp_obj_to_py(foo): - import cppext - print("test_cpp_obj_to_py get_val:", foo.get_value()) - foo.set_value(778899) - print("test_cpp_obj_to_py get_val:", foo.get_value(), foo.m_value) - foo.test_stl({"key": [11,22,33] }) - foo.m_value = 100 - print('test_cpp_obj_to_py test_register_base_class', foo) - -def test_cpp_obj_py_obj(dumy): - import cppext - print("test_cpp_obj_py_obj get_val:", dumy.get_value()) - dumy.set_value(778899) - print("test_cpp_obj_py_obj get_val:", dumy.get_value(), dumy.m_value) - dumy.test_stl({"key": [11,22,33] }) - dumy.dump() - cppext.obj_test(dumy) - print('test_cpp_obj_py_obj', dumy) - - return dumy - -class pyclass_t: - def __init__(self): - print('pyclass_t init....') - def sayHi(self, a1, a2): - print('sayHi..', a1, a2) -def test_cpp_obj_return_py_obj(): - return pyclass_t() -def test_cpp_obj_return_py_lambda(): - def test_lambda(a1): - print('test_lambda....', a1) - return test_lambda - -``` - -## Summary -* ffpython Only One implement head file, it is easy to itegrate to project. -* ffpython is simplely wrap for python api, so it is efficient. - - +# ffpython +## support python3 , python2 + +ffpython is a c++ lib,which is to simplify task that embed python and extend python. +For example, call python function, register c++ function to python, register c++ class to python. +Only one implement c++ header file. + +## Project Goals + * easier to embed python script + * easier to call python function + * easier to set or get var in python script + * easier to extend python with c++ static function + * easier to extend python with c++ class. C++ class Once registed, python can use it like builtin type. + * when python exception throw, ffpython will wrap it as a std exception which includes python traceback info. + +## Supported Python versions + * python2.7 python3, win / linux + + +## Embed Python script in C++ +### Get / Set varialbe in python script/module +``` c++ + printf("sys.version=%s\n", ffpython.getVar("sys", "version").c_str()); + ffpython.setVar("fftest", "global_var", "OhNice"); + printf("fftest.global_var=%s\n", ffpython.getVar("fftest", "global_var").c_str()); +``` +### call python function, Support all base type as arg or return value. Nine args can be supported. +``` c++ + int a1 = 100; float a2 = 3.14f; std::string a3 = "OhWell"; + ffpython.call("fftest", "testBase", a1, a2, a3); +``` +### call python function, Support all STL type as arg or return value. Nine args can be supported. Vector and List for tuple and list in python,map for dict in python. +``` c++ + std::vector a1;a1.push_back(100);a1.push_back(200); + std::list a2; a2.push_back("Oh");a2.push_back("Nice"); + std::vector > a3;a3.push_back(a2); + + ffpython.call("fftest", "testStl", a1, a2, a3); +``` + +### register c++ class, python can use it just like builtin types. +``` c++ + +class Foo +{ +public: + Foo(int v_) :nValue(v_) + { + printf("%s\n", __FUNCTION__); + } + virtual ~Foo() + { + printf("%s\n", __FUNCTION__); + } + int getValue() { return nValue; } + void setValue(int v_) { nValue = v_; } + void testStl(std::map >& v_) + { + printf("%s\n", __FUNCTION__); + } + int nValue; +}; + +class Dumy : public Foo +{ +public: + Dumy(int v_) :Foo(v_) + { + printf("%s\n", __FUNCTION__); + } + ~Dumy() + { + printf("%s\n", __FUNCTION__); + } + void dump() + { + printf("%s\n", __FUNCTION__); + } +}; + + +static Foo* objTest(Dumy* p) +{ + printf("%s\n", __FUNCTION__); + return p; +} + +``` +### Register c++ class which inherit a class having been registered. +``` c++ +ffpython.call("fftest", "testRegisterInheritClass"); +``` +### C++ object pointer can be as a arg to python, and object can be access as a instance of builtin type in python. +``` c++ + Dumy tmp_foo(2013); + std::vector vt; + vt.push_back(&tmp_foo); + ffpython.call("fftest", "testCppObjToPy", &tmp_foo); + printf("testCppObjToPy changed nValue=%d\n", tmp_foo.nValue); + ffpython.call("fftest", "testCppObjToPy2", vt); +``` +## Extend Python +### register c++ static function, all base type supported. Arg num can be nine. +``` c++ + +static int printVal(int a1, float a2, const std::string& a3, const std::vector& a4) +{ + printf("%s[%d,%g,%s,%d]\n", __FUNCTION__, a1, a2, a3.c_str(), (int)a4.size()); + return 0; +} +struct OpsTest +{ + static std::list returnStl() + { + std::list ret;ret.push_back(1024); + printf("%s\n", __FUNCTION__); + return ret; + } +}; + + +std::string testRegFunction(FFPython& ffpython) +{ + ffpython.regFunc(&printVal, "printVal") + .regFunc(&OpsTest::returnStl, "returnStl"); + + ffpython.regClass("Foo") + .regMethod(&Foo::getValue, "getValue") + .regMethod(&Foo::setValue, "setValue") + .regMethod(&Foo::testStl, "testStl") + .regField(&Foo::nValue, "nValue"); + + ffpython.regClass("Dumy", "Foo") + .regMethod(&Dumy::dump, "dump"); + + ffpython.regFunc(objTest, "objTest"); + return "cppext"; +} + +``` +## Python test script +``` python + + + +def testBase(a1, a2, a3): + print('testBase', a1, a2, a3) + return 0 + +def testStl(a1, a2, a3): + print('testStl', a1, a2, a3) + return True + +def test_returnStl(): + print('test_returnStl') + #map > > + ret = {'Oh':[[111,222], [333, 444] ] } + return ret + +def testRegFunction(): + import ffpython + ffpython.printVal(123, 45.6 , "----789---", [3.14]) + ret = ffpython.returnStl() + print('testRegFunction', ret) + +def testRegisterBaseClass(): + import ffpython + foo = ffpython.Foo(20130426) + + print("testRegisterBaseClass get_val:", foo.getValue()) + foo.setValue(778899) + print("testRegisterBaseClass get_val:", foo.getValue(), foo.nValue) + foo.testStl({"key": [11,22,33] }) + print('testRegisterBaseClass testRegisterBaseClass', foo) + +def testRegisterInheritClass(): + import ffpython + dumy = ffpython.Dumy(20130426) + print("testRegisterInheritClass get_val:", dumy.getValue()) + dumy.setValue(778899) + print("testRegisterInheritClass get_val:", dumy.getValue(), dumy.nValue) + dumy.testStl({"key": [11,22,33] }) + dumy.dump() + print('testRegisterInheritClass', dumy) + +def testCppObjToPy_ext(foo): + print('testCppObjToPy_ext', len(foo)) + for k in range(0, len(foo)): + print('testCppObjToPy_ext', k, foo[k].nValue) + +def testCppObjToPy(foo): + import ffpython + print("testCppObjToPy get_val:", foo.getValue()) + foo.setValue(778899) + print("testCppObjToPy get_val:", foo.getValue(), foo.nValue) + foo.testStl({"key": [11,22,33] }) + foo.nValue = 100 + print('testCppObjToPy testRegisterBaseClass', foo) + +def testCppObjToPy2(dumyList): + dumy = dumyList[0] + import ffpython + print("testCppObjToPy get_val:", dumy.getValue()) + dumy.setValue(778899) + print("testCppObjToPy get_val:", dumy.getValue(), dumy.nValue) + dumy.testStl({"key": [11,22,33] }) + dumy.dump() + ffpython.objTest(dumy) + print('testCppObjToPy', dumy) + + return dumy + +class PyClass: + def __init__(self): + print('PyClass init....') + def sayHi(self, a1, a2): + print('sayHi..', a1, a2) +def testCppObjReturnPyObj(): + import ffpython + return PyClass() +def testCppObjReturnPyLambda(): + def testLambda(a1): + print('testLambda....', a1) + return testLambda + +``` + +## Summary +* ffpython Only One implement head file, it is easy to itegrate to project. +* ffpython is simplely wrap for python api, so it is efficient. + + From 567c6fee7c06d48c7f5d2530c49558a351b87443 Mon Sep 17 00:00:00 2001 From: fanchy Date: Thu, 18 Jun 2020 22:12:43 +0800 Subject: [PATCH 13/13] add new --- ffpython.cpp | 55 ++- ffpython.h | 925 ++++++++++++++++++++++++++------------------------- 2 files changed, 524 insertions(+), 456 deletions(-) diff --git a/ffpython.cpp b/ffpython.cpp index de72b1b..fc0ead9 100644 --- a/ffpython.cpp +++ b/ffpython.cpp @@ -152,6 +152,18 @@ ffpython.buildTmpObj = buildTmpObj \n\ } FFPython::~FFPython() { + Py_XDECREF(pyobjBuildTmpObj); + pyobjBuildTmpObj = NULL; + for (size_t i = 0; i < m_regFuncs.size(); ++i) + { + delete m_regFuncs[i]; + } + m_regFuncs.clear(); + for (size_t i = 0; i < m_listGlobalCache.size(); ++i) + { + Py_XDECREF(m_listGlobalCache[i]); + } + m_listGlobalCache.clear(); if (Py_IsInitialized()) Py_Finalize(); } @@ -267,11 +279,13 @@ ffpython.%s = %s \n\ else if (nOps == E_CLASS_METHOD) { if (nameClass.empty()) nameClass = m_curRegClassName; + FFPython::m_regFuncs.back()->strName = nameClass + "." + name; call("ffpython", "regMethodExt", FFPython::m_regFuncs.size() - 1, name, nameClass); } else if (nOps == E_CLASS_FIELD) { if (nameClass.empty()) nameClass = m_curRegClassName; + FFPython::m_regFuncs.back()->strName = nameClass + "." + name; call("ffpython", "regFieldExt", FFPython::m_regFuncs.size() - 1, name, nameClass); } return *this; @@ -383,4 +397,43 @@ int FFPython::traceback(std::string& ret_) PyErr_Clear(); printf("ffpython traceback:%s\n", ret_.c_str()); return 0; -} \ No newline at end of file +} +bool FFPython::reload(const std::string& py_name_) +{ + PyObject* pName = NULL, * pModule = NULL; + + pName = PyString_FromString(py_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + traceback(m_strErr); + return false; + } + + PyObject* pNewMod = PyImport_ReloadModule(pModule); + Py_DECREF(pModule); + if (NULL == pNewMod) + { + traceback(m_strErr); + return false; + } + Py_DECREF(pNewMod); + return 0; +} +bool FFPython::load(const std::string& py_name_) +{ + PyObject* pName = NULL, * pModule = NULL; + + pName = PyString_FromString(py_name_.c_str()); + pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (NULL == pModule) + { + traceback(m_strErr); + return false; + } + + Py_DECREF(pModule); + return 0; +} diff --git a/ffpython.h b/ffpython.h index a89a225..06cb89c 100644 --- a/ffpython.h +++ b/ffpython.h @@ -88,6 +88,14 @@ template class ScriptMethodImpl; template class ScriptFieldImpl; +class ScriptRawImpl :public ScriptIterface { +public: + typedef PyObject* (*FuncType)(std::vector&); FuncType func; + ScriptRawImpl(FuncType f) :func(f) {} + virtual PyObject* handleRun() { + return func(tmpArgs); + } +}; enum FFScriptTypeDef { E_STATIC_FUNC = 0, @@ -104,6 +112,8 @@ class FFPython ~FFPython(); void addPath(const std::string& path); void runCode(const std::string& code); + bool reload(const std::string& pyMod); + bool load(const std::string& pyMod); FFPython& reg(ScriptIterface* pObj, const std::string& name, int nOps, std::string nameClass = "", std::string nameInherit = ""); @@ -124,6 +134,9 @@ class FFPython FFPython& regField(T func, const std::string& name) { return reg(new ScriptFieldImpl(func), name, E_CLASS_FIELD); } + FFPython& regFunc(ScriptRawImpl::FuncType func, const std::string& name) { + return reg(new ScriptRawImpl(func), name, E_STATIC_FUNC); + } PyObject* callFuncByObj(PyObject* pFunc, std::vector& objArgs); PyObject* callFunc(const std::string& modName, const std::string& funcName, std::vector& objArgs); @@ -375,14 +388,16 @@ class FFPython return NULL; } int traceback(std::string& ret_); + void cacheObj(PyObject* b) { m_listArgs.push_back(b); } private: std::string m_strErr; std::vector m_listArgs; static std::vector m_regFuncs; std::string m_curRegClassName; + std::vector m_listGlobalCache; public: static std::map m_allocObjs; - static PyObject* pyobjBuildTmpObj; + static PyObject* pyobjBuildTmpObj; }; template<> struct ScriptCppOps { @@ -745,10 +760,10 @@ struct ScriptCppOps > return true; } }; -template struct RefTypeTraits { typedef T RealType; }; -template struct RefTypeTraits { typedef T RealType; }; -template struct RefTypeTraits { typedef T RealType; }; -template struct RefTypeTraits { typedef T RealType; }; +template struct ScriptRefTraits { typedef T RealType; }; +template struct ScriptRefTraits { typedef T RealType; }; +template struct ScriptRefTraits { typedef T RealType; }; +template struct ScriptRefTraits { typedef T RealType; }; //!ֵʼ template class ScriptFuncImpl : public ScriptIterface { @@ -765,8 +780,8 @@ class ScriptFuncImpl : public ScriptIterface { typedef RET(*FuncType)(ARG1); FuncType func; ScriptFuncImpl(FuncType f) :ScriptIterface(1), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); return ScriptCppOps::scriptFromCpp(func(arg1)); } }; @@ -776,10 +791,10 @@ class ScriptFuncImpl : public ScriptIterface { typedef RET(*FuncType)(ARG1, ARG2); FuncType func; ScriptFuncImpl(FuncType f) :ScriptIterface(2), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); return ScriptCppOps::scriptFromCpp(func(arg1, arg2)); } }; @@ -789,12 +804,12 @@ class ScriptFuncImpl : public ScriptIterface { typedef RET(*FuncType)(ARG1, ARG2, ARG3); FuncType func; ScriptFuncImpl(FuncType f) :ScriptIterface(3), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); return ScriptCppOps::scriptFromCpp(func(arg1, arg2, arg3)); } }; @@ -804,14 +819,14 @@ class ScriptFuncImpl : public ScriptIterface { typedef RET(*FuncType)(ARG1, ARG2, ARG3, ARG4); FuncType func; ScriptFuncImpl(FuncType f) :ScriptIterface(4), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); return ScriptCppOps::scriptFromCpp(func(arg1, arg2, arg3, arg4)); } }; @@ -822,16 +837,16 @@ class ScriptFuncImpl : public ScriptIterfa typedef RET(*FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5); FuncType func; ScriptFuncImpl(FuncType f) :ScriptIterface(5), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); return ScriptCppOps::scriptFromCpp(func(arg1, arg2, arg3, arg4, arg5)); } }; @@ -842,18 +857,18 @@ class ScriptFuncImpl : public Script typedef RET(*FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); FuncType func; ScriptFuncImpl(FuncType f) :ScriptIterface(6), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); return ScriptCppOps::scriptFromCpp(func(arg1, arg2, arg3, arg4, arg5, arg6)); } }; @@ -864,20 +879,20 @@ class ScriptFuncImpl : public typedef RET(*FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); FuncType func; ScriptFuncImpl(FuncType f) :ScriptIterface(7), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); - ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg7 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); return ScriptCppOps::scriptFromCpp(func(arg1, arg2, arg3, arg4, arg5, arg6, arg7)); } }; @@ -888,22 +903,22 @@ class ScriptFuncImpl : p typedef RET(*FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); FuncType func; ScriptFuncImpl(FuncType f) :ScriptIterface(8), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); - ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); - ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg8 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); return ScriptCppOps::scriptFromCpp(func(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)); } }; @@ -914,24 +929,24 @@ class ScriptFuncImpl::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg9 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); - ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); - ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); - ScriptCppOps::RealType>::scriptToCpp(arg(9), arg9); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg8 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg9 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + ScriptCppOps::RealType>::scriptToCpp(arg(9), arg9); return ScriptCppOps::scriptFromCpp(func(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)); } }; @@ -953,8 +968,8 @@ class ScriptFuncImpl : public ScriptIterface{ typedef void(*FuncType)(ARG1); FuncType func; ScriptFuncImpl(FuncType f) :ScriptIterface(1), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); func(arg1); Py_RETURN_NONE; } @@ -965,10 +980,10 @@ class ScriptFuncImpl : public ScriptIterface{ typedef void(*FuncType)(ARG1,ARG2); FuncType func; ScriptFuncImpl(FuncType f) :ScriptIterface(2), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); func(arg1,arg2); Py_RETURN_NONE; } @@ -979,12 +994,12 @@ class ScriptFuncImpl : public ScriptIterface{ typedef void(*FuncType)(ARG1,ARG2,ARG3); FuncType func; ScriptFuncImpl(FuncType f) :ScriptIterface(3), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); func(arg1,arg2,arg3); Py_RETURN_NONE; } @@ -995,14 +1010,14 @@ class ScriptFuncImpl : public ScriptIterface{ typedef void(*FuncType)(ARG1,ARG2,ARG3,ARG4); FuncType func; ScriptFuncImpl(FuncType f) :ScriptIterface(4), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); func(arg1,arg2,arg3,arg4); Py_RETURN_NONE; } @@ -1014,16 +1029,16 @@ class ScriptFuncImpl : public ScriptIterface{ typedef void(*FuncType)(ARG1,ARG2,ARG3,ARG4,ARG5); FuncType func; ScriptFuncImpl(FuncType f) :ScriptIterface(5), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); func(arg1,arg2,arg3,arg4,arg5); Py_RETURN_NONE; } @@ -1035,18 +1050,18 @@ class ScriptFuncImpl : public ScriptIter typedef void(*FuncType)(ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); FuncType func; ScriptFuncImpl(FuncType f) :ScriptIterface(6), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); func(arg1,arg2,arg3,arg4,arg5,arg6); Py_RETURN_NONE; } @@ -1058,20 +1073,20 @@ class ScriptFuncImpl : public Scrip typedef void(*FuncType)(ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7); FuncType func; ScriptFuncImpl(FuncType f) :ScriptIterface(7), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); - ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg7 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); func(arg1,arg2,arg3,arg4,arg5,arg6,arg7); Py_RETURN_NONE; } @@ -1083,22 +1098,22 @@ class ScriptFuncImpl : public typedef void(*FuncType)(ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8); FuncType func; ScriptFuncImpl(FuncType f) :ScriptIterface(8), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); - ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); - ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg8 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); func(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8); Py_RETURN_NONE; } @@ -1110,24 +1125,24 @@ class ScriptFuncImpl : pu typedef void(*FuncType)(ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8,ARG9); FuncType func; ScriptFuncImpl(FuncType f) :ScriptIterface(9), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg9 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); - ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); - ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); - ScriptCppOps::RealType>::scriptToCpp(arg(9), arg9); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg8 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg9 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + ScriptCppOps::RealType>::scriptToCpp(arg(9), arg9); func(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9); Py_RETURN_NONE; } @@ -1154,8 +1169,8 @@ class ScriptClassImpl :public ScriptIterface typedef CLASS_TYPE ClassTypeReal; ScriptClassImpl() :ScriptIterface(1) {} virtual void* handleNew() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); return new CLASS_TYPE(arg1); } virtual void handleDel() { @@ -1169,10 +1184,10 @@ class ScriptClassImpl :public ScriptIterface typedef CLASS_TYPE ClassTypeReal; ScriptClassImpl() :ScriptIterface(2) {} virtual void* handleNew() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); return new CLASS_TYPE(arg1, arg2); } virtual void handleDel() { @@ -1186,12 +1201,12 @@ class ScriptClassImpl :public ScriptIterface typedef CLASS_TYPE ClassTypeReal; ScriptClassImpl() :ScriptIterface(3) {} virtual void* handleNew() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); return new CLASS_TYPE(arg1, arg2, arg3); } virtual void handleDel() { @@ -1205,14 +1220,14 @@ class ScriptClassImpl :public ScriptIterface typedef CLASS_TYPE ClassTypeReal; ScriptClassImpl() :ScriptIterface(4) {} virtual void* handleNew() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); return new CLASS_TYPE(arg1, arg2, arg3, arg4); } virtual void handleDel() { @@ -1227,16 +1242,16 @@ template::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); return new CLASS_TYPE(arg1, arg2, arg3, arg4, arg5); } virtual void handleDel() { @@ -1251,18 +1266,18 @@ template::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); return new CLASS_TYPE(arg1, arg2, arg3, arg4, arg5, arg6); } virtual void handleDel() { @@ -1277,20 +1292,20 @@ template::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); - ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg7 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); return new CLASS_TYPE(arg1, arg2, arg3, arg4, arg5, arg6, arg7); } virtual void handleDel() { @@ -1305,22 +1320,22 @@ template::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); - ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); - ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg8 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); return new CLASS_TYPE(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); } virtual void handleDel() { @@ -1335,24 +1350,24 @@ template::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg9 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); - ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); - ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); - ScriptCppOps::RealType>::scriptToCpp(arg(9), arg9); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg8 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg9 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + ScriptCppOps::RealType>::scriptToCpp(arg(9), arg9); return new CLASS_TYPE(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); } virtual void handleDel() { @@ -1377,8 +1392,8 @@ class ScriptMethodImpl : public ScriptIterface { typedef RET(CLASS_TYPE::* FuncType)(ARG1); FuncType func; ScriptMethodImpl(FuncType f) :ScriptIterface(1), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)(arg1)); } @@ -1389,10 +1404,10 @@ class ScriptMethodImpl : public ScriptIterface { typedef RET(CLASS_TYPE::* FuncType)(ARG1, ARG2); FuncType func; ScriptMethodImpl(FuncType f) :ScriptIterface(2), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)(arg1, arg2)); } @@ -1403,12 +1418,12 @@ class ScriptMethodImpl : public ScriptIter typedef RET(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3); FuncType func; ScriptMethodImpl(FuncType f) :ScriptIterface(3), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3)); } @@ -1419,14 +1434,14 @@ class ScriptMethodImpl : public Scri typedef RET(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3, ARG4); FuncType func; ScriptMethodImpl(FuncType f) :ScriptIterface(4), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4)); } @@ -1437,16 +1452,16 @@ class ScriptMethodImpl : publi typedef RET(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5); FuncType func; ScriptMethodImpl(FuncType f) :ScriptIterface(5), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5)); } @@ -1457,18 +1472,18 @@ class ScriptMethodImpl : typedef RET(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); FuncType func; ScriptMethodImpl(FuncType f) :ScriptIterface(6), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5, arg6)); } @@ -1479,20 +1494,20 @@ class ScriptMethodImpl::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); - ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg7 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5, arg6, arg7)); } @@ -1503,22 +1518,22 @@ class ScriptMethodImpl::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); - ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); - ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg8 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)); } @@ -1529,24 +1544,24 @@ class ScriptMethodImpl::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg9 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); - ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); - ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); - ScriptCppOps::RealType>::scriptToCpp(arg(9), arg9); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg8 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg9 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + ScriptCppOps::RealType>::scriptToCpp(arg(9), arg9); return ScriptCppOps::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)); } @@ -1569,8 +1584,8 @@ class ScriptMethodImpl : public ScriptIterface { typedef void(CLASS_TYPE::* FuncType)(ARG1); FuncType func; ScriptMethodImpl(FuncType f) :ScriptIterface(1), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); ((CLASS_TYPE*)pobjArg->*func)(arg1); Py_RETURN_NONE; @@ -1582,10 +1597,10 @@ class ScriptMethodImpl : public ScriptIterface typedef void(CLASS_TYPE::* FuncType)(ARG1, ARG2); FuncType func; ScriptMethodImpl(FuncType f) :ScriptIterface(2), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); ((CLASS_TYPE*)pobjArg->*func)(arg1, arg2); Py_RETURN_NONE; @@ -1597,12 +1612,12 @@ class ScriptMethodImpl : public ScriptIte typedef void(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3); FuncType func; ScriptMethodImpl(FuncType f) :ScriptIterface(3), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); ((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3); Py_RETURN_NONE; @@ -1614,14 +1629,14 @@ class ScriptMethodImpl : public Scr typedef void(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3, ARG4); FuncType func; ScriptMethodImpl(FuncType f) :ScriptIterface(4), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); ((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4); Py_RETURN_NONE; @@ -1633,16 +1648,16 @@ class ScriptMethodImpl : publ typedef void(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5); FuncType func; ScriptMethodImpl(FuncType f) :ScriptIterface(5), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); ((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5); Py_RETURN_NONE; @@ -1654,18 +1669,18 @@ class ScriptMethodImpl typedef void(CLASS_TYPE::* FuncType)(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); FuncType func; ScriptMethodImpl(FuncType f) :ScriptIterface(6), func(f) {} virtual PyObject* handleRun() { - typename RefTypeTraits::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); ((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5, arg6); Py_RETURN_NONE; @@ -1677,20 +1692,20 @@ class ScriptMethodImpl::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); - ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg7 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); ((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5, arg6, arg7); Py_RETURN_NONE; @@ -1702,22 +1717,22 @@ class ScriptMethodImpl::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); - ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); - ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg8 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); ((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); Py_RETURN_NONE; @@ -1729,24 +1744,24 @@ class ScriptMethodImpl::RealType arg1 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg2 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg3 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg4 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg5 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg6 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg7 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg8 = InitValueTrait::RealType>::value(); - typename RefTypeTraits::RealType arg9 = InitValueTrait::RealType>::value(); - ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); - ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); - ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); - ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); - ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); - ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); - ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); - ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); - ScriptCppOps::RealType>::scriptToCpp(arg(9), arg9); + typename ScriptRefTraits::RealType arg1 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg2 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg3 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg4 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg5 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg6 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg7 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg8 = InitValueTrait::RealType>::value(); + typename ScriptRefTraits::RealType arg9 = InitValueTrait::RealType>::value(); + ScriptCppOps::RealType>::scriptToCpp(arg(1), arg1); + ScriptCppOps::RealType>::scriptToCpp(arg(2), arg2); + ScriptCppOps::RealType>::scriptToCpp(arg(3), arg3); + ScriptCppOps::RealType>::scriptToCpp(arg(4), arg4); + ScriptCppOps::RealType>::scriptToCpp(arg(5), arg5); + ScriptCppOps::RealType>::scriptToCpp(arg(6), arg6); + ScriptCppOps::RealType>::scriptToCpp(arg(7), arg7); + ScriptCppOps::RealType>::scriptToCpp(arg(8), arg8); + ScriptCppOps::RealType>::scriptToCpp(arg(9), arg9); ((CLASS_TYPE*)pobjArg->*func)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); Py_RETURN_NONE;

^E=@Y5LN_9>v0GQ|k+?@n9U=>yC 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 *z>yN>tIX0;m?_~!E^l>|8#lp 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ᛸ^CdpKTG+p>w5Q!vlx;Zwp@v7VL) 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�SgZgLp>_2OYen6JD|-_KqPemKRx@Jm~6^=-63x%x%2U*!3LxU3c*KyW_PFN&Q#^?Or3X%G2pyBK&qxes_Tj@xI-H9{$ULXEmuitKgL( z0d8!6(tj+Rwm1F1+}r2x`_EPp?o+*WYYO3h7r4*%AU{v{KH(w{#=jS1+gghM299-P ztvud5N4&NRUi+2szZm@YaOiz3Fs5)JIU>2f3pGpD5(ONwd`z@!uiAY}VwEc)k73-X zdbtB*?$ml&i*URf9N$CqT@8IVkvgAXO5iJ(S*rR6wFe~lY@x~Vb#zXpgU9j?F8&~~ z=10GMNj<%YGbT&%`ecVbyS4TUKG|#yD~?EBO3(0%#NvM$bF1=K&4ITS;r4cL`!~_G zo$5LY@kHgM#PW6sll9X!U=lz5L_B;OJbVfJM)fQ6)sc{ zBBf3AvF2`g@jIgXT4;VVS`ETu8|Cq!!x!_3c6UI#cZv3K;K^z~&JoiNhX$J+uVq{E zUmk6KZPC2FLiCGO{q~@5(Lpqj&DN~Y%b@S4WZWz|?raAa1u$mN z8#boR8q*UFjW!XD?u14Q9bFwGYxXAf>-`RmmN~}#nfN9KJo&!)(&WA? z+VAV&=kg(3maC1*)t^KMgZ`x=%_JHwhlXF1+>S?Xw;?%rJ904gz5muKi)jENDvmL$ zhA>+$Hz=1Iz*o?d_Vtai{xhcz5smMH#%CNlTy*$mG||76>R&&E*~WB>@_f5P<0SAA z^^BUPU?YdeNl9;RXdW8F#=Ty7+2$|S zAv`^ynm2L8@;BM{lw@kC4Y#8lP5&kO%w$;`E2|7OkkbB?%LIk3I$*e`S6|E;gW z>BEZqf@9w&iRV_qb8`b4WyFNfG1OQ(Iq+^J`EdvG<0s;^eehaN63a1-C7obeshF-h zV(sO?TfyO}8N}lo;qf&gJa!&g4Lp){DI}izy?ElxU*z2{|@JAJgxL?pKHpSHp+p35N&N z6MadYNkE-x3SDJBwDJ2s#(P9@{wNi{-xbm?<8}Yt3R4lQ%=I=7dB2C`bWO~*2A>33 z7~j3w{#f*}xLoTwMRMUT==RKg6qR;MKK6&s>N%-itZS6nBi>iHyBV$9@tq*?YSrmj6Ca zNInr!&QQ)Wn}H+fdvTRSKU^`4CEP7j?ou5X8xu_qLX*A(|E-GuHiB!I;yOWU?G|{k zvIEmvQUelE1O6mFZKghb1)K(R(9c6-mcc2@HBa`cuEM#zZr4{iJ>33!{~MC$dy(fO z!An#v599_|!|YkLZ`K`o$uVqH=gKFsEw{&mcP93mq>I&t_34^CeqQ_#@ zV?V(*SN;1H;XAWp+d#Cs4_XxgZdUWs9hi?0Oj8uoufQZ8vfj5f9#2QYmtW&26RmH7 z)@KPP_#`}h;dwNBqjO^iw0wkMo2c0O5}!0ypQNdlqM>ZI<`(hJ%}h3JNnY+lUT$)5 z7I*o-9KFtAc-+9Q@deO(b^OfHVMECol`zE4oL)G?K zM_ly+z6L%2p3f_ePhuR6|BoTqX9ut!CH~$Be>WlA^i^(Nb6~6VcXZv&iTd;pyduZw z_PGJpw>{yN-e`T%`lAg*8;rITb#4f>kE(gMLHpfk=N(wu{2x5cBs|Ru@RUL{o~Ihe z_lrIs*u}$-&jcl0_E9c>AReiKCu>}G#C9L?PXqN&Zs3Z_CxmQzJ9!yqZYOzj0C}^5 za5gi**{6!z>Wd-0EfMO^Ah~=yw9MzgJdp6%TX}qw_<0ljT#aZrS2Zl=7CUrUW|2EpG`@vkSE?}6q;5u5Pq&t3k%vG{))BCDwJ{YbRk3~d*Yv3uy) z<4HZrg?jV?@%bV6{4n8ddVsf*1bcDdF5zKcY0Bbnf_Z4yZXL~R(~R)i*yASSN&)vY8oNuwu0Z6R;i^>la78);^O z@+pyy?x=iSh9AKEja*ev!=h)wFrV!~ZXtgZRWRcC+=y){^sN><&8iW`aFMvDYHH)mGg~wu@fV-V48VCA!@T-Qt(Ialb(3 zraZ`j%ZMq;53z{pXELAehmPZj|8v6s$H249wRW>>nQUOWo{?3!F-gEI_v72G06rm5 zHn~?I?|(j3K;Hj3S)b)H1IKW3tSj$ES!|Zzk-jS(dOr#r!FemAMy8qq{|9G}5wA>F zuN;KdQS(C{M3)yWKUzVwr8sITg|VXe@b7!~k4q;IeYZp3q`RZ**a0we5N(%(gPz25 zwbXORiD#2M?8dwT9^_cc){E>oUXU#gipV>7Q_XN33yv{k@!1bkJZ+YmH09RrW9P%d z-g&DuvzB-#7y3I#ypxKnvu$uZI|!p5aK!r*;t6VQF^K27ko>w2`E@De6}z9*g_j(C zHdJlp@8wHkjm18b;f^U@UBtD!kOr2Inw|z}=9nX%3eY|(KM#TPPk=cq#OJ7lBC>O?JRdwmAlD=yWxuA;}8dS|F-J8*#5k3wE{oEn&wv+xl?6=8A`lxFT5~^ z@G>mGOM+wEPDGbDRJW4ed1qr9klIoJwdER#xs4ZdjCr1TW*0njBvdmkU)6NpDoym5 zqIxVQdJNUrlN@p1Nql|;K3_vP9TMPlCNzmU?zj({97Zeb7<&k*Au(PqVBXylUB6nZ zkFF7)=Yh{R5>5sy_E909S+AEw{*-ZGZb-D4tXe!rw5+OHPSA1fc#_AmC1DMkMB;6w z@!m%C=%+EsIseKI?4J=2-Ubh@)7%Q?7m4Q|faf1jj{O|WSmO*pJOeeR<_@EIQ0}S_zvP8q1^`dg@$ORGCA9)aSVKdv+jC*^x;#nqNy5_u;OPhAr=##w zNy7c@;C`%wqa%c)yx^z@cnE53b5_nXz7PJgNjv+Jr9dz|Iica~~v*AlY7 zY_Vo3xLRt4hA`Q`>u9=~$B7R4pu+`tB8tPK@Wg{?3zerJ4>E2RjJX+jWgTcYdpwhB zs+;yW_8Ws2`VlS*fX9Mpx1kRi-)`2k(nnMD(wum254@MRee`kCgYfJh%C+<>*e%z6 zwf?g%V$WiZd}^953Ig{QKq zVyeOeJ;Bo^2Zrwn_JY7Znt109c;`Jbx2B+ObgA&)c}TR9O|)r9Ja-J9D?#Gzq4DO} z7p?Dc==)+Qm+ZChAQ$CG|J}9!Wklx`Xj}yCb_b6qh`;1Xh6BKd+}C1xNW}kyk=bBG zRyXl@x^pgE9Vr6NOW+C4RS3>*iZk|u=sC9#_8*F|f}XIo-ybJqjCa8otL^tX;=JV8 zZ#2f1=MC8{4`PzdA3H11OPopgZHmU4hNG$*agGz$mq^TAHRhc}o1)OA7}~3Z|3vhC z6_{;}^y`hUL_4iHlO29-MsRgeTzQEWay{rKl0SDMe@-|!t_Yt;%_$GT=O@r+0B`X8 zfxUkVPjT_M&INXdk~}+(JnKMW>Z~yxCR`T>&n3{#IIx!^e2BMul5sofxXTfjf40?k zP%gM7!#|0hdve1)1=T&`of*iazlpwWRo{VR+>Sc#T8vx7AJY4`nyKb}mpkM$<8QJ7 zhkus7AnLt5F{hX*ZOUR*Ep@gjX6jC+hmlW+A8tnC`HlYh;qf?c=%2@*=HZ;F=kn*F zLdv=PrRYie&!`I)LJ|DMIS0pWi9a5OHy%NI9QsA|TN06cL-HgW@N80FSsZpfBE5-z zH{ylG#8(f&S4W87?}AG8i7$$x-_b-Ld?FgY(#&NC7uPi&!EEcR{G1)}BsYl8`!?!} zsbt*tI__tVao->umjcIo!DE7e&`qL{O`ghVKhs6-0Gx&u%qTLaJqjH=63&W&vjqfu zJH`I91N#x+tE|}MTQ_{k77ITL#(4DM*Jr*ivi zjcQnJ)WB7X+PGh!F3!f+$NBh%rjcoEnjlA-ndYX2X=!dStxRiN*=UP%^|Hq8h}`LH zx?q*v&2&c=^~6fBx9Njy>Td?%XnPQHYLa*EZ8q)$jWHh*-b;h`mx%xN!hd%V-#!fA zt|DBvRW1t+h|Z^+@YqRkDYe>q&#p;lf=A)98a&A6*`Y*VxiZ`dT13qOMNu1yp`F%o zJ>l?=UH8kF@|i@jTcgL7HTaVR^9;qjMftEX$#+?=6!MO<@SYr!SFJU#(n)PJ4vv7t!DVG+0eECJ?DGe%A0&0|BwHJ^%x;S#MHaLq~SElH>sIKr_R1W8c=klRFjq!tdV6{pB zhH~IjUbDZ$kKUFFE`KC3kJOldA+L|n*LM*zJ=OV#PG# z@nmDQ-v{cxDc}3G%>LeTaS-14hIsl>czP~kiPER0)~UB0m^u<|3#+#G6Anv*!)zp; zp&HNo7&mx~W{=wwfXkmt`(f_GIX2>-WO%0l+9wYDc?pIgis3w|(T_vRC(sI!{Riv* zqX<8Rl%IM;vqRAA4B@T}xGPS^9i-#_fS98+ZK?UX)8XHTNG_K~E?-B#QMI5s`fZ_o zuOf3uA!tznxTA7eewVL9^m&Vu@aSCukBYBty-&sJX^i}0MRdPXBMt`kmE7>Zj47}F zzDDx(N%VYyXiyd!j6>~_XWYtpir`irwI>a&5?U3sYG^gkYN6FZtB2MAZ87miLG?x= zVv5qRsq);5c;_B?CkgvT>C_neHqreHlKva&>uo|>+4)!2AEybYa>raM$oPivRt~&v zByktexaX0YUICmHBbXZ~<|A4QL=THsel85}l|yStJa!5mOWGgpzo+1Xa>}RlC7V6w zOTf{df0Vk|+(`7e7kX47xa%wK*ekw&!?n9S`1+3IV;SV*A;M*T<#L2W!;3^iIc5k`cM6mtc_*VEu@62=wp+IZ~uR?1vc(sy0$djQetG3b$uH`4$ne|@`NiqnZi6m z@~k5AY^4Lw8-&Na%H!J5zE=Cp;BqjDrIyB0A|`r0R~BB+(lGj1O}u&^$-N`cZF2~Z z)mQ4+LgKS0;ImP{DwyqNmWkaKz2?rN{GWEjvjF@>)u|W2--~G1NM2V)UXQ#I z&0%G5c#&}b0J!gtyo?&N9P%<1tzL)^%VR3eRNY5%>`COaj+&-zny-gQL8J z-`vV?OY|%8*v;lhD$c!iz%TcNd|~}7xqmb9?@Qo*_LXRUtAO8j7&Flhi0}RrG5x!x zJ0L5kfX7899p}8|E($!?ITWA8kQuLa3h`oJll=OH=y()5rV?I~l$Sn^evdggxsz~m z7M!#uc~lH}wDw9gUsb`^IpUkA;F}>1oL@S4JB=8u?!uY>Ww1{7&tsH*I6CL6LanhF zGwOI$?sk`Z(0k&1teks#R>!cKNG`~E!Ghj-!DQ2zXpl=a$bBvPIQ~KCHz^c%MxLdc zhe=&{85+ETwuf+C4P5^b;>`9dbL2)cCzpp`XNU0En8ksm2vR-;+1HPYKSihUloRx$@40}#qxa);rRr3K1Z}21#OFg3+dC2Be-Nc z4<537811vVh_Q|XOE==dXW+pHN&Hzg{>h>EZGOo7w3ldF8=AHtekrYb^nX{viBkR{rlK-h2Vx>`ypq435qd%^!v4MF&M|RtDaD+@VP=!uvSz{uAN0 zA-Ek!a5e$XTftA%8oa3I5&v5GGLnOr!0!u0n+mE;@~zS9_e{#~T{^z#BVVGA%$X?| zzldU(L-02P{!WCG+_-b;4AJgIXg6N-219w{%6HkSAa8yq+MR@U_XDqZ&TiIMa@_yE zL%UtXqwj&kypKftp%JuuNc}70S$@R7g_N7sgq!Bz=Hn0^i&gMfB)Y_@E^UcN%fh2i z1~d~~_PDKp9>3yH(cDksy^MHs{19D#Pl4apa z%c&Qu5}q4_=k=tHR)ZhDBtCixK59pJj8z`bD_4N$p|xBU^z@U@H!$XD!qxlW>JZ_h zCHPpN-j}{*v%ClwccthY z5#J3|zU+STT{MhQzCI(^@+-DegpV7*M}g3|ekJkm7d#J+1+)Dfe)P5v!0{Ed4H~oj z(#PcE%B9}wM7+}k-YJH0EgyD&`CeLm_XA=I9v27(sd0G`Q$CF=SEuOp^jUap7tx~t zuw_GQM)K(?XmOVC)e3w~g%(k@tfPQm_1|M$K`c7uQM^@2%q2ADStKv;slNEavlv1# zSs�_%36zM?eF1-_D$v*v`eqRQDL#Dh7NlPbg`FT*42Rm)(!5_2}No%vw2_pgG-kI}v+ ze6#@{g^3SxYfR~c>*g4_1=?7x72&*l27Eq?_9BTnhZi$G^PF&2P&q3Hd{G{j`FIcE zq$D``i^SX(F{gkp=`+mbC*bND@m&r0u4afU>**XGS9p#H(eD-LcZgsu1+0q+htGk( z=g~%kqaX*CYdQA46yn$Badz-4wPOd-uO(i+0qq6i`80Sw*GK-iVV>H7!$}TI%^jMZ zBs`P`4>O1t@*qx$|I1LUmVb$}A}UvFqEB|!rxwYRPoeu~XrqaKuR*_#j+jakp4x+_ zTS>inL9``YlmQnH5#3rrv({*T5H1ouE{y5pz`F`OOa9o+Kl2=Y-~Bm)u`DolAbIpT zxU8w1*fFe!3gZ{W2)I^TeLfaVO1DTtqs}F`bV*8Q!xgz{LhWI0!`r|0k>P2X^ zJ>+*AkN7f2o&^|}Z?Sb3Q!J@IJYgagQRt`U1YXmvAyoImtOV z`dF(9^zTkE7gNm3h(8k5AHNYDQ=wxT;WA#i?C;QdH5pg(Qu6eqLx*)_UwIdy>^p~W z`6amAMD~^UwaC7g$h`Ct^5HDnb@(f49&HD2-Aek-qJ8&94T##eHuC>DqVZJK_!#ll z8}L@r_UL2J^3douf=S+OB=NQ+8fH-q_mcfH>HcpzbecoFS5&>XndtNtbUH}Jl_$*! z?s~-YRpI$dgv%+)$SqD;L3iW&fNQf0HABFA+b!2|r#7 z#cTT(&dU;hJ4pUG#@pd|Z5Q!b5%t-xgu_Y7;UwkA;*{?)_vTZMS`ck3LEA@&hra>$ z`G1Vg%U9r+^`sWmK`j_cyj>06mN(}`c~^edk>IQhob!nfGHHxi(699oy83r+o2VQ; zOXB<&o!Tl2sFBNw1JAz=X z3ancQ)>y@QS@YE9zHlttHSqTX+OrN!Kaw0xMvkr^Ua1bR^dr1?0`D(5#;ZuYFhRZW zMrdCfQ(;re%pn|A14rKy5B-Sv4-)=jl)sWh>vPchIg(3tkxSi(4_<>0>N&K&?1(Yz z>gZ#{!lDO>zdGW-16oOrS-w02;Gde%sxI1e=w)-z)*|_vF3_th+6izZbCliedobjk z=JM`Zxf^S^cW-{WX+bm`uNr<4iqDQG>)2BmCs<=FUKuCTq3E3Z2^tn5yvQd#e(xBs zBf&aOu|7k*fiwR2GUfxKe?92Gjp$JWdaMNBm>Te&nDUlV?|V0J-5sqDT3@t5XoJy4 zpp8Tuhc+H<3ffe(nP{`n=A$h@TY`o=S8%#9n^}#v4sAW!X0$D6JJ5Eb?LoT(Z6Dfx zw0qI+LpzH0Alk!dkD#4KdmQZy+B0asf=lZY0c__hISMI^Gj>ym=U<2CdpkVeQgh7q z>5+kd-bRj{B;Ku!Nb94ez!y>8{u#db1#J+~c&uuCi0D)kI$cyhT8~;>xuO2AMEm;C zKKs@G&Xv~3Qm1y4+Smj9jwe{hDAw0V&20!C@?gv;ZR9=jl3OQ9oV5^Vb;9AV;O{!x zI-={F(Df_AQ66wK%b|HUlCx!yvq_nv*TN0J?P9{wXyxc-5@&71*@ndV8)Ez&tui=_ z2Uk{adwnSrbQA5W;FbM^i?_hVdV+0~Vw*?il6TfMm>pk!ZUk-Pn?$eYlELvP z!ece?_#WY+4!EdK{31^i5x;DAXjhTw(-8U$Aa(i=@VkfblUw5ARHA?j&3A=`V+DKg|>>|Y6e`#$=JDc?0-nS z^~A@7|3={dB?qF z=Gjg1RW?C^cLMEg95<|xU)2q%gN1J>*qI0!Abc;C|&3#YQ{?E~G zR$#Ze??*4s0Gh7x$omvlm^TPt*_E$-gs=YKYc{lqT3^XKHs^+3vpA#{d;@Gz`%Q;u zN|SgSAl}O%tTw;0p*P8|>yCc+klZpcxaS+~VG`#k#Q6ysH&MqO2wz0am5ErD$+~O~ z$*;!9uNoxYhKM)QPyc<-f_=_eHdW9*v-8^!KI{1e;1iw`L;cwI;%D?DURZ3llHAIt zxz&s0dQ<53JmGH~_&Y}Y9}C`d16$Aw)+f_}dm`aAlk)mUC~oVAtg1^Z!fhjPTfi}H zY?c46eQdw++HXrbBF&%g0@gJn-T|&+Kgz&HkJX8jraJ~p9IZ>NL_k$!~njl|>5ssRGqrxGMEWeTk z;;~JH|5%N+F2NP2xZWomX9CC1J9t__@}?Q`rm1RUeJ?!77K1T=Cmb#XhiRc$tw*H} zO1qQ98l$n!COkF;k7LNZ(hKv-52TJ}1_xQtY7<;CQwgq%q{igc8q*bgUTCr4C<*Nh)(DxfM#zNs-eq4CeNN*haP~mR>z1>u;6$GIu##}n z44gD4amiT(iEALyF*EQz8XDL7GG4XFa!>TRhvqKYRA@{aYZi@l zD~Yux)-s(*tWv2Z)(457o5RmdxyD`8NHMhy{t|%VC z@B6`40Dmqx27SUcQjR6E;Hhbyut%&?nxXr_suNjf3%?rop)DT=HoY{(7pZ1}z7nC4!HF zXlJ2kbCZrem!K^-!wAmDfOC`PmF300hf{K@EskF{f%d;Ql$&V?xvp09s==>^&bHi9xnrX_3^bz#Nd2sSM zi8)4NK1b%y-k4?Xa(JpHd>-Y+7Vvmmnm+@~Q-r4+;Hjj>Y2)zo%a{@x=LDip4rr4T z?T7>KuY?D@!yR9^#78(Tu450OF_kiJlbCWLrc(|~*>*LnxrY5Q>y=RV*-2L(WS$ z+c~;okmDt$UxYvVdR<^jNBf#^lnah#5ij+ImtOZ^x|PK82Vz+t(aYwA%sE#OZgarx z=tvyagC)xCb0nAFK`u9eo~}Arh<8g5!?=k*x%I9D4!-onxy2L9aH4fTXgw$56RSxz z)#P!)-(TRbi+WRXQ8qg#4a4=WyGS19g1?GrS9$Q3MKD=@t17?6grj_L^culya6i{j z2$w4Cnmz37Zd;Wf&Y@4yVovK`)={X`5f_BCGe9S)2H>N;Lbxu zofzTWzApaR?-_47@j-w1panS1#Qyf2ri>+9HO#v;&}yMI!<;)AtpGefjX5{GqPEeT zNA#+qdVN7OiH9bSc<^S7aId}JMILn~9w-F1lZeh)&^R6K8PAx%6RZiq`YF*X4|?q+ z926@DuXx71NOcjut(Nlh0O)eMN9)IlC;P&a?bJW9{Yjts@Xsj1T@kq3N8%{bINtNb zk-a(0gXowQz}+#zT|T(`%+u$$p4Tpk=q%&PF-0acmRzVw@FW4xd~hJ2?P@`C;@^Jo?>>+3H<9?OA^sDI9)-{&--EL+i9Hpue@Qqk2sj0AsKl#Wedrt4BV4oC*Q}@VHU1+c4^uP` z>m<47)&9_V9>JRlyj?ta$CKPD0_PuiymJrXyaqTgBUo~PWq=1u6~a%R@^cgMWHIy_ z;psPPhMTt`@W4^Rd9rf8fy9!FSSEPJY(iqGWVHr=DKLUPZWd3-RulZyLaU8d2km@} ze=~l+7hkbkf{DYvvc?rp$vFqS`Jz+T1B)S#64YNFLbtBqC%tpu$u zT0OM-XbsRBqBTNmjMfCLDOxkM=4c7{>4c}dnq=aSl4 zjM}-x6UP^%c9tOD+mc!}6t!w7iKDj0vBopzlVsiTA?Brb2(MMa>sg*Y&Cl**?7E0! zI>A~iz*=G+1n1G?cj0(jd^!}vz23@${LXSNKMw;BrxX7Sgnusd;Ozu0WlY(^xi{=t zj%9|K9_AOa9;gl;o+TcUD^P`mhkD>)neq@Fv!ZG?fM80~`R7_sJYSQw#z)Zf5WFd| z+H(mqzHC+C&3k@Vx!O!us|_40*09n zxYs`?z`NHGY}tx!3-QTF_~bP*b}?oXY4Ta@BcVqszFS`GJtm!@$DH6!F1e3u9gYBv zd7JRxM`P)z9OF;_?oWQM1&%io4&{85)apNo?lqzNN0B&WO(tF}3C0aS>*)oe!C+`` zfN+?l9Oj?%zqL;KPsdCz=Zd~2are-;w~^RzG#SM96Tx3I2LD||$5GHR_h$F;buDnS zFp^I;*E$9HwB9^TV$amrdyI7V{RwJR6Yx?2@!QRML^%1AaMDRRX-+szQ%jlYwsW0-mU;iO7XK2jz2%ojV=RP|27?X{$UG=Az#(Y=A z2ev*{fD2>}Gs*5e9|Di|^>AHCVy+z%^Q-WW)S1}%Ky(`o|BOW&k2Zj4k{W0-;gc04 ze@mc7%?Jit$C_&Fb1~MX5ieT5bPT*W$8;gQ*8%TOM!1uGB?l8VhkhlR$~mN__`3!X zeAXAKF&s_vaNIJozm2b1OngHL{u1DyNw`f>zduT9{4_Y@d!pS$Xf_#b3R=eqJ{w

y9g}1-_7>OB#&t;c%yFt`l#kZ#Q2xucRdi?aRaK2XqxDipcga{EqH0uR zXVBemLJP0=cC&=hMVgT%;ZCxkxpI z`n|qW9jRO`+|VNb9;_nX+t+E70-Z%eS|YWhCGbefX5%Pd9hAH|N-4hP_al*yxgO$) zDc$+~_rH=D;38Q1*`2a5a+{qG7o> zq6Js8AN9vAi5*)LFSK>tl55+W(V*I3dmGLuH0M!{RJmLCsyk&|)fvfsG%@C7$sL|+ z77*R7`BsOi-?t_HReiPS{!Z=jN&N~^~@39C3#EMFn7G_f#sv2Qw_LW`#Ft{p>IR!)~cvyH{ViSqi?h&t~-cy_FQX2 zJc;YNFdBV?kKOf*R5#MV^(1}P{%YrUfV=8we`Gy-)n@4|dho5tf}`WzW_1X1EwkDs z{r(2;>M|V1<4)fIg&)2JJ{?%WH=?&di*E`43^AWlh1GsJ@1GGrq4ZR)d`_b0z z#{Dehx_k`!Y!Zj+>#g8gCvQ((Y?7_8^s4RHInl&OR#(L`EwQn@&s!twi|$ibwpH^i z_jTk7RC}g7`I6P&iM~lpwhpSC$VSVrkREdtoKNz+TRGW^3N-RrziT`Bd#)g}1J_r+4d(Q+<&51LQGO=c~K3 zKDsh-y&bK^rKjQFg!D;Qw){>j5-aVi9Es{Xbp0n2Rc5L2m;Fw^O(QqfDmlhX#;;ZV znfUUkvAY0=zJn4*S~$dAu=xzTxK4+YbLW>=Eay}94yAdIKgKI730GnHeBpGQI*L*P z)g0)|Ix@c62c$ZxLDKfwJedM=VAJ`+wWr?OwodJCbPw9P7Rh&A4?A&v@-fZGL!Ur= zHG;g%Y2>4S zTgPtf#&b0Vxb*e#lf2{@Sz{(O7N z3IXqC+_$H60YAccRacd8Hr-P89J?Fe&Fu!?5OA{l{P}v{bpaWQLN0av{uefZpt@D%~?ZM>4J1b-ypdcVnEx$WVL1K!uTdihXF z3OEH6{?yNw(n!Gj8CM_QD4HGc{>CfPe~COnzy}!j?Mf#He4z2I+*bG>AMioOeS6c> z13uWeZ&x}j;KvyE?MnLve28)1uC!~wk2UVwm9`J~amF()!}+ubxJp|*ZF19CUIISU zxNlclBjCe~`}U)i0)B#V-+r_x;KPlR86tc-+Id?L@xut?zMbe9#3%V|6K|KEXxz64 z9T@PD#(jIx&xyBF|D%lmfW-g3=O}qJW=j z{B!b;*ysa(n(@!D4slrlA8q{8=u_602mEy7z8&hgfMfdRZvzYUxdB(ZDwSH+^S@8P z&ob`Yr*;bX*~WeQ)W!kFkjbBKpZWsnRC?deHSWhFc_`rL8GnKDA3Y-jKE}9je>pYa zV~zXvm*)h0objanWx&T9_w6iu1$=^W-=4C4z|S}C+fz0Q_(bErJ>{+epJd#(rz{Tm z1;%}Q%KwngruX4Ob8^7v8TaiMPYL*Z|<^*NrfG;$zUgA-7LXckEZTwJX zD8t4T@OzB=@qP{r_#)%Jy<_u$-)r2rkE|c?`;7bcl+^>i*tj3>XPbcQJNLbAv4RBr z0potWpa1akrSHju#x(*2H7NmKV!T7tf%S(0UuwL)waa`x;13!1?IxcO_`}BAV%?>d zHsFsKZxgj)y*S{@jQe(+a|2##+_(F@G2qLM`*DUY5BQ_T{WwGC2mCSPew?9m0{*yh z-)?ebz@ISg+gT0?_zL5`U1qOD@U!k19`c3o= zlJPs`*YlC-92;)r*yvc4p0oTZ9JM#O5T5QcC-IYRD~$4Cru)8#-}lk?sPI!p&P6uM z9_x1Ka5NB&MCYJsXg0b7J%pY_FQfO-*XTD?^cmrxT~Q5G7d1gGQAgAT^+f&92y_M- zi>9ENXf9fe9z(0qD~Ud2{Wba(6@E^M2~|b4QDd|(YKsm;hoPS6XmkuZ0iBH0w&YCK z=b;JcLNpa!hOS1}q1otGbURvz6m}Z!{kT`4rewC;qC-$Gq;0JSB^tr{jD$^KeF>U@ z<|ItpccCTd3G_UA1ATSg&S-G#G~yHMn0q0n!YoorEZHFiqP z)`97?&vt>)Ggm#I-t-Jyd(W5y?_3 z*H2N~#Pw06(yZ8qNcJSTsybP;X>~oRw01B}_@16383a3*vnY~0$81wbxVBWy;DVADPW<0D4e^b!0Re6NdPGmXDOHb#&FN z^m@ibJ!kvhCz!oXzi(&t|CMmb&MX_W?9;M=-^C)Ex~{|5@B12leKGGxs$JLqy(8s7 z;34)6CXBZ9v?k@|4_N zsCiW#gnaakwx8wcQ0_vH@db zd@5gUj*~r9e)644LUOf}zcu)N=% z>@_v2lkD|=q?!=z)x>?9=VOT8q;>syGZ$K^LE$tcc9z9b{=T!i1i5NC)obgV`!Vax zossIc#d}$;k@mX-8>n*ha@Qu#Qz=J2nntTE-QTQ0x}GVV%TDeH-a7H8tQJqMx6OVk*G99r%T>Xt?m(`coJxsu?HkGN zCD)8d7Dydw6|D$m)s*`M+F<5&@ji~Uc738Xsj*kNTKjc~R0Ag0QPJMXd8~|NWfuFv z%01d=TY99*W-nUgIBmO^=O*_u>)IsyQl?CN{T6AgIPE)^b}{Rdqx6r4&hm6PmZ0^7 zBOh0j|5~4f@Jci^Ir=B$rPLEv`7ocFls$z%%Rl@SX^c3X;my%KJV&{zL@F`r81+a~ z?zzdkA0h3NMOFMs(kxm3bG@fm6q!ht9O#Cx|_ol z%70n9CmW!SFqOKTW0I?T+APbWtN9XCOQ*f}cCycjP9PNFofQFB?nz}E z*>x@rc!6bIA7wyx6#(kF>$ivh&gX(`-FE@PBP!cd2OH z_oI9&;M*AA%I(>p;qg$NuVKU7@B}CM5X9))N})WkjkLlc}TY% z?7yx~QI@-?r`9;SFmdf0eUi9ZM->nE-)k-Ml)6vySufI)lB-qJJ8`v$zUk^&6U)Wu zd2d7fwkX+W?`Xp2&~uXbt8H|7;_4JVL~z=t4KdlzNiL{T^mDRL8@pFN%u12o2OYgd zv}yD2hq5hJWOKmDRm+}-Tzf_*Za((uT(`n$!f{R?>i5~!-Wd689DT`3u5F{S_|#jt zHz`qTu3k@3zwBV|om|bMv768TpyYlwi3&)Q^j0fX*)Gzv)bUDqf@dba=^>k>^0gxM z7g1P^BfV8})rtmfzP_(FU*E}__x(?@N0Vq{61ML1(#`kzgw1;wCHu6E^o1(yj#1jO zxJmTw=5X|#>emiYNfJt>=-6SNZ5tiC`MmV~$X}yq^yd4y!{%d5N?e_y-!_M=FGzdT zjmB)=V_o8E9Zh2o-5XiSf8bhl*LJWuyc9!dzt-sAzklz*zjxq&!yTx1$L4hGD1DvS zhTH}my9Zp~Gj=Ms9$q=%KAnHxy$}C%L0LFHo%g(A;NPe7@45Hz-y!ht(|OMe0{=dp zf5W|j|6YOrteubNzXrU(_*%CX|KA3@FyK>eFFQ}4&fmiP0`%Goc(M8S{G5Q77@xyv z+1Qx_?$dwIkDgEXoS@n@Ry6#O}WrI=vu4}-R|Mz3FV>J)>z5#C+@coSYb^t8{zJI`*1-zwk-#(yGz*_};;oP$K z(C1Wqet&4$_g>n@{9o@hUd+(}Z)^NIr}1UF2K)fyetxv}0dHq~26F?D?+kc*+=CW-uRL3NccwqA7;E4vsq9V9Pr`Bdon6I zcG7^KXuJobk5l#w_$cGunM;Ry!hoM_{0L^f!NwEtQ;m0HUK+}Q0YA-nXV)3Ny6k%? z9c|pV1FISE(~bLfDwP9HMI(Q0Sa=TuPNf5XzTL@BW#3)tS;l?4lg|QvwsGIyVp+h? zF}|10W_wG(&o#b#q;%$@fS+f4TN`)l!msG_i*7&-7L={;W?SPzEKPo2$@)c8*6KrD z$~wxFt<{!7?KRT#O@B|rTaEv9C_Vqwe|p@{`0YPPV_Iasp=^elqK>EsIt^Wbu0)H_ z**J!Kn%IfHACGN(_`T{bkPx8EDZtqj> zX;+btM(%#Z9xw0=<-XJ1<&=Nr^^e|jdP8$?wZI^`ne?#PE_6 zYmXzN8r*rgrdU};=b~qDty4);TMxU3DR~}>OTOA$?UHz>Xs-LzY3`${Y|Wwe=MLV> z#Tq|>FGIb4)FY@V?`Q`WrIJcPmFk{u=Q4r($%WjFi^%U>;#3aP)m$4L=AOe{3-{C1 zalOQSRFB*bdE-Cld;6aEUOj}=d#E0Lb6e9BUn#s&f8`96Yfz3txs4%q^teCLh~Jnh{B7FxSm>O5YWV>bBcP zPbFu16#k!f%7e<^<-{|}Piyb%T|pA2&Qqm-(KlRLGq!!CoVr5n9O>-uN#2%j+^cQa zQ@-!Fu@?$(4WymV5Ms0oh+8h=33PSWCU462mJ`y^7x1-JNsjrTTjJ&b75?^7b*#U# zrD|(OYN@Zb8I81$?z>7n`sFb0^gO5hqJH@;>gyg)uJTCtB#UzRI;$B@HU;f*3wLgX zQ%**E)T7;qN{jlXU!>U-mFLngGosE;`7-@-bJUHusf3XA#YK#Fp#12ni2Gzm(+2WMLnGC4LWWO-uGkNcgZy@ zaxW+M_*thMR}nsTqKYq?W-RJ?0+hr7eg^f=<}l6xO3W8wJs@83J{?;ZHR=nfD8 zl&k;W-r|`r9w^Uui+3Zcc=sWnAC-MuF$XP~Y zi;ce&zXX3G;9D7gF@6z##KN-URy3|TBPk;X{9~tm!=KqfP4)}n8?`eENya0Y!z-t@7J-!{@D&X~v&yVNB8w9+O z@pw*`11kx_PT-bK=|^2_c8wi;sNjn0`Bc{ z{o;P`kGZZmOa35=M-4RpN5@CQ@4$azx12s0?xHfT@{-=q`{I925dJXZed0dw z>jHkF@!oN7_@scJYP>u1u41PNxa?OhIwC#-ermvFUvg2mxEuVufR8tRczihggn&;n z-ZkzD?-B5ejdzK=z&ivSvk>8TjyuB#2K)-+2gL`$4-NP=#t)1Sgx3i;4ZsLT^G1`m z2>30=J2JB%){cOadBJ~&xC6Xe!0$2MK5h^H<-xM|fhYw3?c#RujRAkyc-y!wyf6so zG2^Y{*6>Y%|0j*Nid(^73ixxzTgENn%LD$B@%@+^F^b*^_-n>n#4X^@1pIB|nxPY$ zSHRyl-YjkgpBwOxjW>;(!Y>Q>M&k|Q2Jlz7`1C!*M96*69M6;m1O9!$mj(Q19>6|&e;ME3I2lp+djW4}{5SU->ooyC z*!ZvRSJo>6ez@^p+%K#j2)OL*F8bO1%z9qHRUhDNW>{Jx2mBc0Ke``TPYw7m<3G3` zSdR(#DC6I|?^&M|@X^MB{}k&8-}U0M=XI0u zjcz0BF9Uv?ao>L6gMi;@+_xWiHQ@Ic|HOU5`k8>=Z~SBTG3(NRFE##=`-t_u0WUTF zq5F{aZ2@0l+_x*ZKH$#={Kq7H8A$r_qVaWZ9qVcMPt%t*Y{yXif*4EV`E8_esKGwuVuP7jmPQ+)MCo zK{$$E@&cZQv$gRT+za^c6rAUF#%1Lu{}b>XjX%TuwX{16_%6nu!d8UcEa26RYqn_e z0RgXRd<|Mb05x|kpE^nNNm&Ns^t;|K)d zE4|N;9&is3&Wiz8z9Angn7*5*1Frl^zFDeCA9Y;bPvwhx86O^xU@e}PaOHdQqkG-G zgtIgVNBOY)Xc2ZM^3Opy1B?%gPhc&chNJvnK2~LY-wT3ph8UN1kv=m4Ki>F4w-7!v z;KPmIMJ){9W57=|ekb-3+QSC?B;&Fd5kCifwDI}aN6F6w{5<2n9=}JxCmQ$l_y-1j zig90$UoqfU7@z4BkJbtJwZ?t@{%!%k$+)lIj{~lJe13G5yNYl&-K%%TKQEOl^0CA! z{{A@NcN_Qh`)>q%v2kC&zbN1j8~645s{;PGabLf`Jm60o_x1ai1YG5={G@*W)_}ii ze5#wud0rdvw~bG6Q{ZC*{(*7d9^mAFZ!qrL0~{OhFOB>507nJ+Q4v%zFo>k0bgL;w?A1I@P)>G`;%7#zR0+5e{ybeA69T57902NPgdhUz5fru3#bR_ z#`TJ)=lPIv-|q3@fG;!d+dZxf_;TaE9pfzlf719N?hwMiG~mw}_w8Q(ANJk^?yI5w z<3BTZ+Ba>|u6@%=sgzVGlom@uB~+GFM9NYrg$UU~h-8`Ub-TlRe?vOPSq@BBaS zYtD2}xANrqJ^$D5_5c0#ZSFJYbLPymuDRx#I}-dQ!*_SPEByQff5Y%Tu8;5& z6Z}2Hd%NDkk4*3n4c}Fk>b0_z;GY@Z%k>gIA;G^iyr*M6bZ~-yYj_W>0cf6*m*d3r5Gl$IUpofQ6xJf2q+Pf5eWx!moOcuET|BMabN z6&^gsv!&tTyzb9#FT}SpJe=2EFA2Z3;o-dQatU6`@Ni!D&q+LW4G-saf0N)13=ijZ zznb7p4G(rLpGfeQh6lTr?|g_QC}3Wq7a`c}0TvHaysiyfDG{G`yaxr+DThcz?r#{l{4ezPI7E zU2TP*lHmIp9_&I+O7J0u2YZea68s>;tGQ~5=k~n)e4+L;-0)!Mag4&pb~r+K+1&mk zcx*o-4G(r6hbQ=G!-GA?!3lnZ;T2s)r8_9W#~2>$Jnos`#~L2&JoZTN;|&kzhwqT! zCmJ5?Jhn^lQw$IG99t&%bi;!^$A$@xu2I=6*mEqO;Aa~i>^c6H$gAfX9?k==k%XUT zcxLt)OC1g{|Cs$K{ILXIYIv~ExFW&t zH9Xj7yeGjQF#Ox>Tg7unf-f^XoCkh=g0D0jJ0#*m68s6n*JbO3pPAs#7#{3A&Q0(a z3=j4krzZGIh6j6&BNF^I!^64XLlXQ=!-L)7z6t)G;lYk@_XJ;Sc(5bfA;CW~oRgBW ztWAP{YIrzjyIF#NZaC-7h<`}%b%uv?wreN&*M^64JF6!6_l5`ij|B<-qv64B<1e=s z_PbvU4|W^BOz__g5B3>9PH?XdTUJ&mRw|#bCU^4G(qzk6Bz8zLMd=p4z|0uEz(0SCJ-4PsQ`F=u%}}>o`BH zvf;sg+3EzZVtCLyeJ#PO8XojiKT7awhKK#E-zNB0hKK#H1rHUbTix*PS$E~5N`h}~ zc+i_|nBX-G5BA`$lAJ0ppJg=-U+$M{elst@YZ<=GFB5*h)@x$;I)-23FA;tt_*9!$ zE~{(!JU>tPrAhd048Pc4Ed0zQe0{?&@)rp|ISJp$@C*Hg!p9|e6T>g?%#TMTcyq(g z_vZ`WJHcBTKG)9`Uaqh`EZf%bQ#|waLp5KH-_^?S6a9(8>nHKFG5lD6tnexc-rn$I z{4v6jZ^U>y7(U)3KR{j)@f{2w=f?>@Uvlh-cQU+!uONIv627zHVIR=qB>!Cu5B9{b zNbnsE$DV}jQzdv;!?B|xxkrL`GkmcuN=WXJ;5!)}?2k`L@a~4+ER84a`$+Je4G-t{ zj!*C&hKKWe4^8l%hKKWe4@&S}hKF-{_etmlG&RHKEUvBe)uy9KG5)BuX9y`4>CO1-+VB^ z_clD(-&~U5`xqYVZ(f+-`x+khC7qSv`xzeW&QDA5!G?!@Kob*uf5XFmpRNf$#PG21 zzf*!AV0f_4*fPNnG(6a6te@Zq86NB;)=coBh6j6yRT6xd;o)5CQVBlX@SxA{We3G) z!{s=ac(fd65Kod@DtDjUO1T&0UY7fpTwN_k)sx#suD)CYxrTC$;$0x@_%+f4xkqye`4`HMeS>%w@2FK8yHpPM z3a9)yFPF1-Dci=6Y8^@Ma4s+Jzbik_!9JJ!MUHSOw*Ak4410*MG#v58x+AW+dQRGJ zeJ8s5h-5@6!y6Nf`{bymRzck(#@;D++yd{4vY&)A9Him1ice~{8gK)(H3}K^x0#7@-A^#`)%Xz@~oW7 zG;L!=%OKWE+U|;CG0$l^rg{3a{QlW9$|1&?=Cx=UZ0@tzPRKvsIXW+w{|QdoMcZL4 zpMQtPZ`)XzZ!Sjqe^xg!jiTX*pSB(Ap68L4q~%Mv0eKrqal%he+D;l@EKjg2@-ikL zX&NyMSnRX(9mWR2(obT#DW0agN_034zg%fW8Xo%!G(5I3^7BicpY&bg-0}B6f0r=F zD@+#8zq^ldke67O8^e~Z3}YztbhXNk@fUwBiJH>!7p#M@bo}LA;_M}y=ak#Q@`D|t z>&C|aIl?c=pQZkyd;vTY@5d`~!f!<$BF3?)_hR^TEWbwS-X=$TLANK;ba=8ze_l(T z(?-jQPm0ePyTW&QmcExhD;h6#aM&i^<=O3<@hna2i#+_FVZ>YAhy2EHDHgv!KBN7m z-|%PO$2(=-e-S5dSN#`o;(u`?@oWyB=4ErrpF9^0 zM>>C2CozpQT%3Qbc)W0qK{(4%tW3YoZ@-A_noV=T+ z5#I&7J`Y1(#&$!TG2Ij|8fTiH%kw_PIP+*8XT*4KZH`^>kI*&<=Zm=w#uw6Bw=6tQ z^FTa|OOy%k#k{3>nm5vj-$M9in@A^yA+4bbvoYFI^jZ2&%tx%Nv`*8qiRBFz>uO_I zI(KAlIZt_-uCilJbgler))tPbVD|}IDfg}LIB$AE_t4GQ_TJTf%yZKfegJIbq|wv46z&LwpY_zLY;n+s~%j1Nhoaycf%fFk2T7 zWkEer&iCIF=CT8YXBt;1U#^pMKV0pT@|+_-vV=INrv5I@<4MaVr6Z&jzio5EkZz1W z$}nzH8ssy|H|jm3oyF=)hkOf&k^c8dQ|${=Z{ zU}-xg-PktcHO7Tp<88hF-7_r|^@Vny?OL6Q8%x~HzF%Lny5m3NT_Z6en5 z^Lh^UZk|8r$`AP)Wtz(0(lC5S%uCuo(z1t#texkhXkUo$ zBAeqK^4VQs`7Y9lSNzd|^;4L^awFtUmYXVfVeY?G*GF>yYr4KC$Mx$3>!D2mV9+t# ziMpR7cfK6);lCmA-z`7b3c0gNyX^QkBxC=V^sD5Go+Scyxx%Dpid>`nyXBscBfa}? z7Tu5=c9-Tm#nHx|EeP&K`_*J`d_VxoN zhbMPs0~UukcFJb?`>F;1AUD+CcZg0y(HjrSUdIz!k9|qfVl3MKQ)|&*=^XlRwR`q^ znvnKo7k4EbCytlbIhu7`Jy+i~kR}J`ZMSpVX@4|l&3Cqw=68~2&#ux2>LU%JJ*0Jn z6^s3}&;J11d3><++r~>LZi4jaj+gG;3DO6gA|1kM(mR|kUB#KU+aJ3NXGz0yj#*PU zPgWV&Z+ww#W?UluQ}*{>F8x<5m)s_O-6gV8akun^@0G6dL(*?vA)V+)rCY(f?I-w3dl0_WzJ>3#*WpL^lXg!0s@)dahoQY2CA4p( zl=hl*(*ByR+N-m(_V@JCo}gX*ZrXXYhjuFs*G{hy+D*1dJJ7DvuC*JrGwv4cvU^rL z`Cibjz=Em42FQa}l9bopNq%|vmJlwl;U}`EJ^Dn{c1M*Yx`fp1v5wUr&@*Ij;ai0+ zkpEZh$lBYZKTDVk9UArcUU$c-ZxgzlukYDk1lrBBLk@J2zugbrDxe+R&;h{;#va+h zvM6!8_Q-dN!fX)++Wz z)?U#lCB;)6dx`LM@Mr~)=a;h6{aGGeA#&2lz2w=?L6~)}jq*pBja5zZtgCivj6E;pyQM?(kuTWKeW7>pjr8mSCFCvsUe8J) z=&`n@itom3=i@@mXZYD#y*}T^6IT|kU$?w68znvYv$b|U&!daXd#5?Ht?`}X(8H&0 zmblUWD9>&-(%V6Oj2)Bshig6iMo}{S1J%ZwtM)s|zab47A+6LSRAS?E8ZtSjAE(Pk z!J5Yr|g|MNWiXUW-0 z?V7#w;7}SPl#^E!Cpv;W+ff>W=%eF5M|OqoRDa~{8lGKu_&WMpgTlL2rS*BAz7qWp z>TJ4JdlzI^ncgKK`#3bQ@lA8=NyAsn&(F)PjdH=xPS7Eqy;u0Yb!+pGHGMzbgH^DV zXna>?Ppc1=l@CoPw4m5Q%kJ7c^t)3(_EZwGw`cbYbJ`>a zEj6@PGW6^)%5*C-&h*YlnrA%vq?BW4$BHl|jg_NPD(M>XkM^Ub)iGWgAIJEK`kkQP znd+mn{T%(!K!Gk^C{34(r5$sLdiTA)lKK@fj`Zl3;rq;Xc@p=wqB!gT1|8(tiw%06 z+D1H&=jIHJRi5wQ&;{msFOB)Vw3!+|R;2!MbqH}=wykC=?250ZQDcn8^>g%;Zy)M! z863jY@a%Nv%>%XXxr0cAHtVSM2M!{RyJ(#e=H={Je^;J`WoQ^VXlDQ^AkU+hmXIWA#6tuFTLB!FNN3ju^g2ZMP%7?;QI%@nwEU zPDz_Nbn2jKZ;88l&M#~h?%vB<`hWO^Q?XD+c~Bzvs~x?dcJzuU@mr!8@5oXUKlZw^ zZ?>j#%zkjRWBJYoZjNUs11X;18suqzVQ1!uX_SQ;Cwoyxx_4c5Uv}R>K`3L{N%Lq# z@ZN!@Lr-kjeK{+S?RZx<@1^XILaTzXLo@X22rI2RkIpSCpd2n@TaKVq~p+T1A=9pmhLfeNzaH+dd@hd7sV^R>>oWh zgoek2mx>xP3)H&Ds1?(4(RL^9zK;EO_?~jls%?=9vl;Mm)Q z?;^)8NS?o`)Q-$s&-K}nDjlA$HSKtw_Y{A8WIh%&^6VK0?Is?R{qltE?>UVJ-(Kz; zjTJl}p)dI6DlQ9y4bM?)%uUoRd!f|7x)Tlp>^a#Gc8g#wB3%^FH*VN z{B7cAZx^StM4aMM<9F`%cl&$vgUVGG8L6i@UX|Uo{%ZdRYrHs4bB?oRh3P!aBreyy z;a=_Nd};kWf%!o?4=Ab8?La@TV#rk&hvqK%TbHp11>ZrAT}AjNI`$jm`r*HAY~*4`eG#ktk)S@)vr?7REjJ^JL-{EOM`9$N>L`(Ci~@OWSKe8b4-tdiIBcp5@rNitl{0#D}krNBb1t_1QJK?~aTe6<{SCI>5wp zr907MX8`mQhlLk>2lx;25&TN=*=MU2RTK&@jWh=N3$hpbDUu7M7RW66o)_M3=FYw* z_--*BWWN4X=?$LZ*$F`WuV(C3!q>^Mix%Ixjx_^(Ke&B0&Q_I=eJ|{ZVV@Lxu7cf2 zcJ)!yjK7S)W8C?E-+h>e=zZtKwH)e3igP(iJ@Z{j7v2{Kv$dy(UUX3SYUERB3zOQd zwqKDv?ri-2!zz{&b@yO0&*mJ)w@lI!=QTg74B4f^&K7pVR2BtnAR36Iid|atROT6x z%j_?z2#>@laj@low9P7@+b5bVioO&iP*DbTxn}FB3@RN<-~zCk0N+t`RAB}XiYB_dWQfgi8 zd)PY)KE|G0Sh0X-#cuxfY$Jh{OO7f|1FZCl+4?~4leFOzeWAzNR7(Jd+Z7G z_64@HkT?3M-LY#N|2&PbKj}&yf?Q|v9wB_qj2)T0xxZtNFuqe9yUuv8jeFVOTrJKS z4pZw1bB4gbp>s?4?J{;H5x%5b;#=mi9Olq%2ff{m^Gij^q21@{*FsXQ2mBQp6QDcv z5-4@-DNyS<#uLB|ATj(+4VBS9?LT$$@9mnQ;Z81Y%htyQ?Su`CN2kR2muQU!PNU)aZ=7vZpvOB$a*rsA-`*YP%tRl-dhrgWQQd_I$ww zZj@>sUn!3sIKJ^_2?E~(4%;XAK6UJR;Oz?}-+Aq{fYxyAQRn$AhZP5W_qhG@akZhZ zKYc^KzP?f*j+Q!|s=jCq{ujg#vXhv14|D8spgiI9=6NiH5$1Yvc(XOP+DCqRc#vHn zzo2iI7X|ubkKR;oMy|ZEzWhJwy$4#q4U!b3DfHQ!{cM#|MdcWY;Ai62;Lw_y)Q`Rg z=Z(bf0FV6+zJ7(Pq7USIch;;0t#JH}#KW`0gHmCJe~CYNa0oxf{W>g!VN}I>4YB;w z{hD(|v;+3A5DWAFRVN`i2>C%m8S_+IrALmCE`~e}@w=+65L+|1DsL4>njIprUtMcu zW|hUnw*`48d(zmi1~2oSzLl>nIpRFlet`eXOZq&T0a2?@)Lkh$UiWLVaPvNRVlm<~p)DrbX>)G35%k2P-4_HH> zb|yLYDN^U(W-oa5dg3qR?(*1+BE&BaOLX{#>bO}>SJS`0M6s}P{YTF7zeTgK{{82( zcy@O1RefbU7b^{X%W>}0Ljo6`$bwWp2l`{hRY*{vSuvx@{pu@70uHPkdM9(HwxZUw zJlb2)SuE#z6aO8y?*-pjvjmCnCC^@aasrhvUp&Y-4pKU-bHObjgI;5^m6YgZ>bA2$`RtjkMitJ z=bg3=J3#pEc35g6AIM~}3IaOWvCj?kPB-3n$@v&~EcOQy;u4RA5`0q}HY5pqt>oS8 z7Y6+~V}~|qW%0Ae4+;{+z%^DjZV@{SQ1p0)_+=hj5WKOsyVqmigLuX}EJcEjkPNn| zS~2K}uIYIJ)lM77o?y_g%=#0)M;-RO@U3xeRkr)eS2*Vnv;F^Mp8wyNGsq&){^fu&no0h zKTE&U^*ckqGjr+uSy~NcA1J>dr9WS*j~AG%9!sReI^SRE_Ys9=?i}UdFU<_84EFI< z^J_D9CX(`^3>#1Q<~yux5(ivhH^qTWoqgan9M&5LOIrAt?e&Fln&dt9d zj^-8j4^L|Piql1v6((|Y^f~5@L0-GY#n}*jFUpg!LPWe%-H)1=_mq#_>hKU)C&6+F zR!y*Yf>jvib0b8Jp~vGT{bN3d1P~eExuVd}=%7^qrDg_#$kW7P{=px6n;hA8$$e>^AD6P#6ljmKD(pnSG+FZxM&tz6?KgOw`i2fGT=*_=*s;X7g~#$K@523WrwS*2 z<~eg5dnyTYxLJe3H{D@h5Z_wIj(gsFUM&{ubD*o-<+*Q-8@Z1(9))elhmF?C+h1LS zWd#;ZjDNTO`e8o8kIR;O?D3GJeH@mu@SX0k?MsfYkqnr9r=Ulh1szaUfv{4H|0YR< z2dgXyQO&WJ9~8b7I~({by0iVOxu01Z_IwCE$YIG5-^XqnUGUZM+o;tsj;CuNSbF2> zZ4R5U_@pY?TYzkX;E0#VX*~4-r%XR zS4m8tIV{QI+sU(M9p6R1vSM!~A9Et=I<)y9y+}FURC^}s#cWJ6LEC0N!z?EDIV=y7 z+CSX+YHLuV3cj+fTb-YmGJFR17RdAC*=>Gh&T~|ETRZIfg7=mb3ftGj^t@lJ`P>%r z)zQw?27aV}-7h{bAjs>x*h(Hdt9kPZ?Wbn9Id9&TbyTl_pW87zU9=SHN$Oa^;`tai zbwGFvseh)?oEYFJrsie(Po<8HHbS52u#$*xnZu4NVV$_cc;5YuX8n-o_dD!U;(N_~ zrN5uZO}CMnwiG1voPrWGKMM7!kW8(WRuwfF#__0GwP}exS|XJ-tF0l)eV8{zjjO0P z(ptJ#aIGEJ>t2QRaws4=D*d$*xS{S9yzjQX zR844=)XBEd*xE@FlD)ElTKyZT^(wSnD(YDSoqN?rXUccUx+|UC_3mKBIYOx%rF4$Z z_8c1GXsmF}rH|M>>!A=s^z>+(*N`4LBv)AeCMTm!TPDp3tC-}Zr6k@RM3wf`D&(PB zGh}u0xPIYVYKu2J=&lgM@C^Mg-sqC;l;>=;>_db+_07M&j^f%!e$uRy9VZ{<%GdBE zd<9=X`&AJMn_%bI61uFNDTc3K_HUC$eesZ$EdH}UMMj`(G_jd{WT>^hBfzB%m$4UAaeU2;RjHVpf56eT}+)7lw zx5DzQbT&>t5f{;cZPDz0B;Yl(_Z|v(c~SL_*))an3ROk)?7aNls@ZcnT3uv^)Cs}+ z1LbGLE+_rXW*S*Kh#njwjCs(OS!4C^wi@xv}od4DB@zC?&&uQ(*4$Pi*g2OY&vbS_q#2+O% z9F}GT(qhpXX@ZlEqz%%05$BTNVZLyp8NDiMP0Kr1?qGPZ+x&QfcQriNZGJGpdm4_ekk)Gwytm=qU3cNvCAipM{R?)RFHi6RhIf;$ zn0Dvs6ZQf1w;!CPNGe0iy zU%_tk!3qzRSNWgIywOQdeh1|f97<2UOfWpybKXC}CmJ5?ISucP=U8@|2UUh(Xe z#D9`-ud^*99^;>Cc(DJxOA`MK!`n;CPOUeOzrNx>-SA)+x>FMWnZgUQLOjNQj^V*x zblW8UxrPUO(Wm6`H&*-?8XoLLH%a2ZSa>n%ZMIf^z+?QE8Q#jZ5?(jKuQa@+G+4C1 zCXc_l;$LWZ3)ez;)g=B!!nct2PsC&V(1b0d3DaER%O&yOVt6y{&QiV-{0_r8B{|C$ z~`uJkb_^-bb` z&+uSpdsQBPXT`tP@L*^A(j@+mgqPH65caphWBi{P9_(*lo8Vs2iJx*Wm6da(vwMO! zG(6br{xnZ_ccn{vEhSwz^4mR0mv&z|!DG5@4G(s?I}pBXpi9t^(jr+hL6Wsf((PpU zZ`p4u*Cq+Rqv65+cHIQ;Zul?K>Xj{+1n*^du*>~(p8tW$e{aKo(uv`k4J&*sH^!SX zLL(mYzn9@ZNN-r>oy0%L@L;c-@hgVk&+uTc`=?cf_yL9od);N!*`Vixm7igTf1Q1; z_`g*6n4g1%mlYcE7(e52S?Mu{Qd+#!SL5I`tcnJezM`gj`vLoKGpDG$9rLd&oDgL@xCm`luAOW6a;=DH+)z9bzrb+x8nlkJvJjtV_itf` zgPq|n%%t-Z=c`~8h(@Quy2*eKVI=KGd$QOZkEKq zLU?)Yvb|C9fXDb(86NBvS4!|F4ZkkCPT^}N_%ntFyTp`#jOPWzugR`a_+M1c5r4(- zg*uB}vf>1P-SA+?nEHz0-!?qhF{ZvEzQ*tc*#gD$MuLB2c(7x!4C7h1g~lMIT?J@h&-RO zl+SvG&(3BGpQG@x9O?_-QfS1t&~y4%Q^U`YHGnLek;LE9@LAa`;m79j&sO|x44;|J z6n;Vye>>rogho8Z-_h{XveOiPToQk0!)Ijhk2CZ5&r$rGOIk^5Wz&U^OycK!)5-}R z}L41Y?|;vNj#kMT19BYV?6x~pOQ^c_$4P6*5d%fPtHyj zenTGrMT&nP!%xzV9_iG5d-qkfDmGT}+?e3l z*{`YLmArqL@NbVQ#BVfwf62Y2 z`J(tE-?G^7L8d)-UXtz|h7ZV?FP@p;OAXKMfhYLAh6j7#;}V>6<*I7Uqo3k=Aa7T< zs$DHNysxBhnyo8*?7xo)MNM^;xYbL4BypsdiP4=f5Y%_e#D!3{C6wyNu6@xLd$x=`lp;4%IW z4G-rvbWQMo8XnG%*gnC(G(4O)(JH|?&#t=Um&gxZP3rd-!-IYGu1R}v1%waw)te;o z6gRxRt&`SDaL%)qd`tW;&arF^bh zU%$(08y?Pa^WtOkdS6z@@I$o6Da+n_tPrnj_-<}D;Zu`%>KVQ)Tc-FAP4I0DUn-04 zvc>gCVLbH>Z)F-k?4p>^q$_t^P=fttM9`iX>KeZV4EA3a4pJj_-)Z1c>LB)g~5IrHfy6j zb;6BMTt)HW4~24PO`b4UDa^`y&}4OXzg+jMnM6DFlo@`)eyV4b8}Cwo@x6ueZ|ogx z+sE*mn-(^C|7u#%j&H2f*oMeo^$ITIzO}At9w{r{>nHpmx%h6{F4Oi#T+{NnsMC3y zh%dggQqTX>HpBOCtR0XC&Jy@uaaXCh;rA>M&iAZVAM2uLd{1oq@x4*Pk16ur*}CVw z%XGa?j`#3mw=tHIsL4L1Sau5J|_+A zZ{MIYMdyU}Nq$#7T8MSfdqwN+NMW?~sk+XUD_Yjjga20Cd{gXKtCiNq?qgXO{r)r$ zlvny~MeC3@8NZ78UZb!@@k`ZaNvme%KnI)YN?q-m-yfuF+6F1FNEfH;S$vmr zitnX%Kf&TV*r$!(wOH>imwPUcgD_xxEB3l6SH7LHBhTFPt=z{rNHd0|TpGMvc%O#F zJ}~u4Kcnu*6ZT^x_Lb5t`i<+Bh3AxAbqP30lXyN-K8S~Mi}6IPr^2Q2Q2srh4s}3( zJx0&db`k64+Ku3}r=nqF8~bnMBi0)<_y6rWr<||{yH?-%eUUQ4CM;zQ?X6HXlr!HA z9ggp{6uzrmTDI}MH`N|SsT3(KzPeY7K7l!nE&NWV?{ zL(%$5`$DX*|LMCcG&g}3#&o$a+P+8^TmC$weNjK#>AQE8qihE23jK}cMR|hHNbvPo z{*4-bZ>WRG4H|lH^uK1&Clw;U+ z1>3hwkTI(EC0As10pE8Sas@Bn0PRCZ#shjnhO`;qttQ{c_h!aQKE6?|vsCx0$=5?O z{!=AYJ3|t{%Vp>921$%x(`rF+*{5i%RmJ97>BKfpM_D4kGHWr5@iy6f>*A0P5!>+@ zD;M~_$qJ^1y{1=b9(A{DcigYtzEy1h6Knd+0Lf`h&EA;J;%}|}5=ev#9z z)D+&%bWG82Jwf#`QxemQRTsBtUV2-Gg%EaCw9ofdbkVLdcJ}pj$Q+2Zy-9gUeGiog zD`B9&+S)Z}E0qZP3!pnWBuM!BnJf?AaVAwIZ|aI$$zVGT1S1=BKM0_PFtyj>gO>X?$CuEq$jN<)o82lZZG-C4l3iW zD&78S#RK$okk!d?DvgOMk4c)jPqB77TkUkNb}3(^(z#5%0Ll9mYPSom<+7f_TFY|n zyn9V+e7|a4@Het;7FWt?^|O+8($-RaG*pSQ+TCP>HjZ8eIv3qlw(MIOrB*+C-%yji zBvI(67XEW~fxe7(vs}LwrgcJT^mNFD@NJhNfx_1{L&pT)&JIhg{pE|_+*MkAeC?oY zl%$VGOJX@r7B0{-o}k)@-#u9pB2(tt6Irp|4#Vk zOzX3iwPuVJ9Lm0?Y#hX$I_ya7rq&a`5!)#2_&89yJENp$R6K8|6HSMCu5!Gqq;l=7n)Z+sE_&UBXd?7W- zSBCF=Kwrss@}+$1m+I-k7W8-OgFmTOSktAx*^`TX9oDETSdFtvPFVz-K$Hjl5nTlI z6wqNnzk!+$)^{i$N{BL|lxPdIhMuBh?BS%eLU~bQl-U?}s~QB_(9|w%npRD_?qKb@ zYffX9XJe;?ede@%+WeTj{l2D^)zBJSNQY#!^t6z!(YLmhWQ&ynTHIvygOhB%gu6f` zkU(y&yN%J0Kc^i|G!2T^Q}VKD){AO8)~1R3TeEYC&0AV;?+hCTq!Q@g{_Fc=poEMX zkrvXspoVeWKnl-y9Id)LRwEdG`q9@_1AU0S>dw5M%@W0HDN5JLA=fALSk*jhnD}qf zD29F(x$5qs#oFnj{jEjsk+kxpoyo)TRmiY@z?<_mYRs9+s*P68Ew|8asCNZX1aeKj z$vJr^_iY_3UzA2@xyZSRiT-eLo*yW{yQdY_PF;uela!lh$kFlj$rdOc-lXMYn}CvJ z*8#1A@g$5uqikHE-9K&lqb+L#rsa{=$@&DjIaCzm=?twlV(;P5!^1byu@XxjTXd2M@>-UyS*XY2=bffBlk%`@Y zj7r;UcPbXFX6zMmxSdgN)=h|u(RGH(qJjK-ZGzH88b=@hPI=xGwF)$f6-M$q%XEP7 z)p5o2m88~Gy$9Q_`1^=1pv^>xMh<;Be4Wge0upulYUr(@ztUs*A^&G>fH8^RLH1+S zXP8DI_@&d7_Bm=(a7?uRn^hWRG?vhE(QZS7u9HK9g%mUQu(ETEJV@;6`*9SY4Rlza z9wT56>yNYw#s*fDD8Di5$Al9#BCx(VE$7=JRSjbzE5&hKWMpJ)yi$~vJO+w-pN(6L zkI)=?ZJ?QvYSJGVC#z`GpkKhf#L+U2mxaBXb{R*KzBXQtc2m^Li|JeA$d4`DcDnCi z-$w6&M}dZ%lz+!`qh)*vxhLN@sEyG!q4Uspa!0;Ge(I^8Hc>xqp?=!hIHT><2HA6p z9Wr%z#dMisDXBM_xQ7o4tul<@Q)Y(TQSa?lw`d1ZN57apAFZaPs4u#hpj{mHGWeQM zFU=jR?S#5W;}CW+@L!j0?Z)dXOUvI}bvq_wG`mJrl#!>JLsN%vd<|NO_}fTFcZjlz zA0C)hQc^tD^t0%jp&rmq?amR8efi&awG_4GqC5N$$!XeXl4$d8^L`Z_wA^!L!?(KubG zoRh;b#`7=Kx01t`v-g#AzOJF#1v}U9pM|}7QF?MdLsX=V;=!86f6f6%o54_GR?f&t z8{^E-x8#m?($aO4SH&&b8Aj2kMKiiJDl9W>2$$6J5wb<_c=oLJMt>$d^h4b#inF2c z&7oYcZU*f_yMtVXeu}O)r8UN}0*ZgL1%E z(N<_B(1CjH*&(6i0=+9Etf^y%S_QoiM|X}*c1_}0LqV;7@??ji+* z@^vsOw~x`e{nyjDGuHFG%(Eg_A81w>6^k2p7wA%Gu^Z#vN4rTg!*|EtjxH=Y3X}|u zV(!A+%4>Y3jXtST_IbS=;%=H6N}rMnWz}zkvI?bDSYBwgQRc6h{s+F3Gb|+ckT3B2 z`)Hm%M*J}2$mK>Uu3pdAL#LTJqhZGE8O^k`w&C*Oa|1^kxcfS)k7m}!BhM8rnlR@^ z$NoT#iLrg4O~qGUt@eYaDc@g3JZ(RR9y?FEiJxt(k(}Pb{9}>kZ_FSX>rE)!B;|Rb zAGW)>AbbzgDsG-8CI6{lwTyEfsAK&|^%G5)`_QjxhfEnth-@jvrc% zjbzf_)i}*d6t;q!*A!h+M*VX%rWKC2og6Fm_NLks+D)W$j;)J>z9$Pv=z4hPm&YVQ!TdBD28PYzMlR8M*tUqmI(RopOsb%<7tqV z1lb6>nmm2Ov~uy4ap)8fk+$8S z?}JMY^Beg5NY~y}KEhm{Sv+%iX77~}2?o3mbs1*`(7Tr6{jfCxzuiH+Up(n)L+QpJ zN5^AwPUJvoexOmww_j{J%J^Q*4iJf ztSF$L*eJoFKggKXiLyEgu7<6DyX&V>Bf%N3nTPk$-_i*V9|8B-TYr6mLu;|Ex10X{ z`eb1_lr=o)4}PEE1e2~N2}S$pa4rwI}O@EgsxP)N(7xWYFOYmxjBY}|K zcYlxn8g}&(rD(E;Pnj;dXWbw zcmu&+$(N4&+`T8GyA zbMF$Lpfn~b5Aobc@>5U52x*8{-WzC6e8P!gbZVHX4D7YAS+jVEi-Bg zUu$by_&Qi`z}MC2625`f!tiaM(I@cjXuTL;PopFFdRvK-o60IjS|8|k*01sP$Y^=^ z+FPH-w{u3T!`IIG3BFE7;qdLDaVIdYG@*8uZ&Rz-$AnR8hrJPvVe6l8q7Pp={fBkw1xE`e65Vu z;Oo5JI?-NPJh8B0Mo-{r^Q>>4b{*Mo7?Xcv1Eb_T-&OAKf3XDqIR1zI|K*-4)c>YV zsB^}*A5?>k*X*|m<9Qgz3KU-56MPxZnR&Kl;G~iyvj_ioq+wkQML$spsUHv4VUv<}pt4wWQu_efw*f%@BDdm3C^Mu?1qaB(}g7+2@;x zjj|@TUDo&f3fA+<*;dk0Xro>Rza75!F0n(T(_VRr=ke5%rK);aw7}dWqjU+wj5Jb# z^6RNUi|qS7Vv0Mhk2g{V$}v)gX4w~tDWt3D{{HuWt_1$r|I3+u`6H74OiN;XgRi_# zeefT0@bKdmhBjJRG@f6i=`}OX=c3ir%!r5g33Eu^&bQ1O9vYrk&Q8vs*VJ<)GlZqh zk31rT*e08qzg2U6`>knO0ffX>Ve7u(EpjmN@c7m_>)%qazyJMR0)LmlMoXaJtfKS( z0vjKPPbi89dnVJKDT)U>EyuoC6z8lG>2SPW6vxK6R%4!C&ll_ur9dipgZ`eE;DPSU z)jEvU=@OjrJDgmkea9cIk0<9lW)#d&fRi3B#DlzGYQa?D`zPT`Sv=zl#tZM7;N=V- zT`*dBnFJ5>_Jaxz5`NZ)h4F{^d5MA&!cR@`Fb^+Yz&^ZV6FkhrKk=XF14k!#m~VgR z*+2)V~E5mQo$@bDMP4ISxb4HEkZ3(`e;j`Q<;kzd|@&ic<+;rhjs(lvM z9egYDhG@^~_5|O-@X=bolGc#ge+-XYgf*N7!rLb}@)eDEk{#=Bf_FC@nR%AIQ`nxD z?QHlu$;vgye55e`9)`aq8`;{on1t_X_(R!4x-LoZUWPxQ^*Z&71cz_OHn^tL+1Lc% z)$p({z97MS8y@5%KWQ9|-@CivL4I*Zf{U5dKPfos@6bjrJM~?y%ZNu9DgQI)h)>9` z@b27mU3Z%_eYVvsyj8ddKVIR^k-IRzF4pzMA{g&}BaCZw1&t+xDC4pRbbToI@7E+? z$LH4{^Xt#L7HjIV(sC8#z7uia-D>hTl4~y4Qm&O8dD?da(>9ivVF$v6#y3&Fm_V>#csweOH~J zfa|?Bl>Z5SlAo-TQ~3MbQ6WqNX`tYuMa62qntx91ocAAdmw4QLqJ!KYBYj9*!I5G8 zvWa`fJ?l7~`wN|6`n~(fO;>YLp=M9%>|s|B{?aOV8!Z(at-?`Wk*tptxCOM~YL_YjMyu z?(2)1;f@kLChWw5i3Lm5;CO~+GH$8D@@$wN=GiNR{}!DO7mzf z=h6`FdYv_iJ;>5}HbWY6^RzN?W8xdC{4x`4Xu2uQrHvG{c86-*Q+Hgz9|o;V&VzYPH2ilX<-xflT+SIs=9n)zHcvraYhgX-pIoi@8M zbd++;*F2{h!!=PUm)HHgY+3ep)~TRN!EOb+7i@SpDzDRtT35%7(w7lOGxxkw{K<`b zGt}#3jnk9ex;3GE9@9Cax8+|_x1do$Q~jFh*Id7%_xn!>TzFe|iQc9}7rATogF+Yj z7>P-Dtj1s5)oL}AFzY%4B!7$7tMk@@mTUdIR*&4}rGgZ)_=2=s%?crDf;MwDVF{#Z?D{zelH~&CFZayK`)3gk^DWWG4@&gp0`u7K2h(ce}AnW{;fj% z`!GK&59xIFojoHg-?hkU?RxivMs)I9+t>E@f?J;7 zkMOH?e&=fM^7-ajpR$hM>h(6=q z%=1xFEwz^V4V)R{Ib(g*T(`TrR=TmpwkiBgl>vF;oG9FzdHKI zY|y6z0=Gk68>k=Pp8h!W?2hi@HQ0!XJv;5&!M|0WI%kkC$V>4E*+9U(t6CwKN9ZiG z;dzUgtZ}WL-XXO+bjAzrjJ(I9={`4)<6zNb-1GT8*3fa!t5p=}-DUQJ3nZqQDihq? z{64m2xKo}#rGA2&o9E&(f0-YcmlZAY#9IPQLUM@ySiIh!=j=#nyD>9?Zk;C!4rq$S z>n$5;-`gtPiV8~~rEk(NztgYi{VjP39pn%4+va(L=6#;G9ZtQ)eV&(c=Yq}!cjY5n zkAj{BxbN~2nRU+&`Pkk=ed%+pN$_`=N|0JOSHHUYhT`(GZa*OZ3x`S>aWV^TSe~bz zzNd$~9WJU1NN0e0#cn4a}43jc~S14Uj#&`y{+suIdNjzMjqs$5qYiaDt!U zUsBq{!^r>8yb$i)?28O{N*->G&iZ{Q_jBIsZ}JoWVvTt?dW7OcPKIi4gA``&{Cm8H*79Qk9Z#t&y8Cm zx=)^_h~_U*o}j`tG$vCv4OCyL|E-)#P7=qBJ1B3T?1+jI7<8f@knDxOZ>gQ~jiI-M zzi+Jx>A?Yxl-QTFKh)@1K_!Wwak7HGi9FsWYL6Q%zJzCA=!XUf_4u4|v~aV9zQL*) z-fQ5V)~RRTxWRc_VU~j%ta#h#`HLQI`6Wp}J`kn&(0{GpclxRD)GvyuB#Wz;lu+*| zqY^DI-ukbFe=nzxH)@Q3TYNu%x5--#H0@ydDVIj#2wP~T!QZR$Z?36+h|@y1g&~K< z3&P(gG~436l*d65!8f0(5gYe}?kOKm6}?X~j|X(tY4kmjm+@i#Fdroe>>jKx?t;Ha zWhiH4F)!p{NBhz1PaB)9lkuV?Y>LMI83o}lQU=-}=Wo4}y|@1Q!1~$ObmJ&?%zFi6 z&&s?l9jnn7w^I4$+sJLm^8;>WUVof}iCdYMQNx191vn)9q&wSv?0@uw3gWfZ;en4W zsn)z*K8p%8d$LjK6a1xi>Kf0(PT)Ax3Za;(K;2_FG&U(0xR_RX{~0F!8;7Kc^1s(| z{eWXFjIf-9-ZAeVhpPuiNfli6^Tu00?z!ybHz7iFQSJqegI=%?KL;T1K zs^wG}>GaDg4N7*bJFo!vvf?eTd%l`4=4<)V^zI_1M}D>{sIHMZ{QX_`TgX8pJ`t@b zQSiG`k34ypSBIH(bK}W3L>^Wh@&!AH=i5UfQG)(IsqN4oU(#{}%8i|9*jPP+#dd(|*9}&eT z5*)fAPFv^civLdVQik{Py9i&I;Lssy#EE;(vgHY0!SL>WXW)&ecfpZ4B?AQ>;bHl6V>!zMbD*_zy{VF)#Yp z&bJr7IKj6yyp3-w{Hp|SV|XjyTKEkK-rn$*ep}&-5?l;|{x!FCy9Eg@;iUdGwe`9A z2_Dv;8v7=S=ko;L$-+1Ejf7v6;5`kmuUUe)odn<2@Opk5;b$dyAH$hfXunf}Yp~M4 zTAFi64u5iC`R`?T4b7cpn=T1I(D3S-U2fQZG|cK>HO-|qY(Ikyui~o;PutG{hF8+* zx*N8ip@vuVTMAFx&j`cI`wB(yk%pJ`<%Fm0=Lo|~`!d4Q_A|!tlD?GiwEc`TytvN2 z-mv{h{H=e*{1(E~_H%;anxqO(+s{dcXWC}JVf&e4_-{I4d&Bl~s^Ofzyo5H*7yw82+i&J~ph!s}28HbDRysFEac?oteEMe!bxzxV6HcctJdi z=$Ndsj=S0LS9H#<>RmYWOZ4sB#k#sI;H`yk5%6($7{1!AR``|)zSQurZrv=w?=k!d z_k_YXPVff|N2a5hZh~ty-)qyx|KaA=BDeg1=<=RqkrxcPIF3 zhF|Fx2){kSHMvy$m$@s1-aU0|I~0! zV^;f5@XrlD&&?G+C&AYlevVFXmNX^7zc&1AokcFYa|!;P;j`UY!cR!>pA0|4ohkg7 z1pn3WS?+YGA+qKf)^M*-ObST-2^XT_*6Gd*QXL3iG#~d(M(`){+HNo2%zOUO)*Ao-GgW;Smt$IoD&V~=v>ENoD1n*{ef6aj<*-h}B4QF?=^okN3 zy(gFLsr}5-gir9@4BuUQl_gV7@ZAmXtsR|O{Y-G)m!&zgi`_H9`y1ZN?V{_B3BI@C zSP2q+OK`qlS_+awOPZG8LkvffBCaFBDPN~ux?Oc0s`eJ?A@$_4tMt=+F~JWtd_lHA zc+UifAeaBL%*E%OwLqz`05z`V#C9^4)9kIhi-}v=ok2_ zh+l4aIPU>ID&h+a59d0-hev#&;o)2d_^60qXLvZ*0lp~Wj4MuZT|1kV0$?5~&67fe3KT>)sfp3ZU6NVq5HB9OE6vi|DNyFJ6FRoa4&Q}ZsFVKFZ zPQqW+cwJdnS$m%bKT%-zb|eEz@TU^|3k}9G9`KS`W7`L|E)Oq@@zb6*yovT0s2;R( zLj2&*7~WKS93)jr@MjGV`@k9`_;ZGbePi1t`16K`eP-pAZl0fIFBpEmyPs=p^_54MGzhd}Z?k-(FP4HI@U+R|X`hJ4HX800E zJF2LD9piu9aMm|vbGNWwmc3y(Yjhj#PkqzyaPCFA@AECg!?_pxC-J;(csR#mV1mD6 z_@0tLicTi@yN2&!`&PRq_J?W<=_y>k}&$IQjlGznlC1DJr`)diS4l z|EZsE{w8_f*U;GzaxuP|@;6HEHJf*7IQsKRLfAKHg8`!oRuU&QLrT z=5fXH-`wxnSoor4zPWW-^u7Ny5C3WX6m3gs`mtR>E3Q&mEtQLXhx^U#JO7T>9I5(_ z@zOv4FVT?LR$@Ij5kvc^$`0G+f2FhPo= zQRh{XcsJI^8tHlLJDciZjfG3|Ou6DHYwW7Wd#+ve z{kzKbmD^ixnB3uVW96V(6Ln?(J$vlmUAO6d@KGQAI?1*klML2t%%7S~Gk#3Ny4L%i zTNu!zrR4+HTSDkjS%GV;dEn{NEUxFz6OTsNWBg>Tf#a*5{UrVXU$cxE50d{gWeIbY zV_ruZmu0J6fp{;%e3LONCCnDu>(j_1%jJu?PUU+Rv?b99tvc1lbq$bwrd$%E#(;=Y4t zZVfsmt0wzRhe_^P#rN_^6p4SOY%jKS=S%v2Y#w7dht4l?H!=R2@@ph*4(5E+O-Jnv zpP8+6%t?v&*sQp0MC~Ry;&-mGe?al_?!(zHx$kR}-jMTR(ot;Sv1CSwy?i6ZP+Pto z^rV>doXg1aQCaE7m6IK<^6NE=Yq%P!n_8}(e%Q?1RzECcvQv+FG$G1Di-iCG!tV*t`w-^L@S06itEE(=*lOBP+-_x7!n0;NZaNMuQEiL|bo zyK}TkfozOYDdBp%W`0gy`dd0=jo{VXp>7w?jFgn`cSq;GF`m^Z;u@KK;69W_Sq;y8 zij?}OJs`UvFO#I%(OS~NOI=C7gGX}BI}ghiSzC9d)2h%QEO?MRV)A1)eC={=Rzm)_ao5`qz;Y4*v&5X)H6 z(Bs@hhh#>BitMJBl7+Cok}iKFO{SKf6$H}1U3SH`ch|YCJhDn+Ebex7O+1ojO1g%0 zTv-(%_9x7q+g|eRZ#LSYO4tHBU3BG4*#g6|*BrCIeyK*51)}=cXTz#97TRuCn?OT0 zTA_Sc6yuTXAL^N_G&($DOAn*uUF} zp0aleeVXm{!xk=9mQ?6rSE*m9lk+lU71Y$8+M|M;lD2kw zR$3|TrL~jaTr1Bi26cUl%D1sJ)V_3I386;6%G#-J#i(e#>{b2V)^ClwtW|h=Kz5>f zpja67z)_Nu9Vw1uj7F@Y=LukS`DD?ADVuByf8G-Qvv!cSf}$r7AWcWojuajVJ<|JN zw{(DbmqCuz0#*`OWf_#f>us#Xu};StUePui%Klx)IwxzOtdFvG z%DO6RuB^whR?9jrYrL%gvNp`Rv8^eqnX?wnIyGz9tZ%dS&AK>i=B%f)*3LRSYxJz& zv$oH=KRN;E3!qDYo&h=t=qI4NfL;SS59mXnD}f#bIu__(pqqi-209(xrSE|*2znyu zkf2|}Y5*XCTY-qjZRrcHaH*`mq^ked82bdh5c0WtJYg5(zSt_T7p4Bzp_(xV(b@)$})Gc`$$9p8o zyfH>&aucnwoT<{S@6jIsy;yr6+9+@HU1@zKt1sleKz7Nu@vPO7yJc>LW8IlP`l@QH zf=c1|JpQBo!wT||o}@izOn$aSVgH$E=U5<%FYH5w6t$417E;wfSO2U(J#2PCBV~oQ zLR|~#YqXMCl)@I$Sg0&?Hd5MPN%MQHA$3y;aB@X2^{(FPS$nEi_1ABpYISe*sKM$@ zL-iZ3o^+^s5q)T!Mv&vwk4{k^nyNl@n)=Tf`ps6~IY<5GeD#?N)n_hIf4Ne>tJGH( zsh`|neI!!$NZVJdhcJq#<9N}LJhQR9a5QH;-}s1LbW9JUdf~VZuii~;I zvoN%Yu^J&Ky5Ds-NVPr2_Fys^hLP|xje(0b6A2^S%Qlixy5H!Gg`O(6LTWTb{QxQi zy@A$1U!WzIsb@e#R%vuwEeid*&0N+PeK6gPq~E9goxYs**|e|zp7XuUZ5@xce5qz} zteMkWZj}|)W~!U-9jl|X`_iiA)}A$H!fve^eMf%U{Q+9Noi7c5o$`M0wtH9O#~L>! z?+0W3mAP+%XAPOys;X`D^li(8*x(t_Dj;QMY;E+#W&G=TIiG485Inm}+&~AliLE`l z10bu!4Q#72a{hfSJwi?3dB$mO1mCkTPpyjD;?AD+1*pgphsFlJ$IN~_zUtZP{vj{N zi&9`Y9(20tPC*Nf)Eu;tR#j(;4%hK#yi8R_Gk_e?^f2kck?4PgCNWm*~q*+4$ThBM&{*lfN4aK&zr>G zHB|5a+_4r<>Sfga+j=x>c>i&CZSFhHS5OGBZ`WJ=>z}crN-mj^4PIXg)$@?wnPvg8 zRuTp3;^*aY9m^|!|NFZH{(n*eH|jgf%N6SX2K&FAUoDEOgQ<%x`~%L+Nb9#R2O5jM zaOgrcWv@TWhQGER$IOoYF%!zN{SqAN0DX|iGwYY&PyuH9)r5}{jvil0>G72^{8w4& z*3K2>2TG0}p9TnJu@L8d@>9`p&gPQ-i^4~|vf-RZqFHN#S2O&_>_=TE=joPHx?3Cm zgU$g^*(B-K)V&uP@fd$y!@rjWbWy-0{`!W0D{3W~T^|3IiocQJoRp$*NW(gW%z`}KYD#xU!~dmSzLE|k>2}k7F`*HU z@%J?RbB(5wize~!YWQcGbxR*4kH3cE-`(&}Wnn$6vBmGw^i+8+#AEye4F4qiMAt`> z`1dyaW6kU(n@RA&hHH1eu9Fh{0K?zV?lzrQmEc1S=L|Q^jT8J}!(S0Mqjs3!hZ@eg zZ(0LS@X?09C@Dmi?VR988vcUDFG+zDe5~QmWg3jKrU`zG;m>9ou(DNoxiwL_9dG#4 zItfJWUg2Z8ouK>TLL(l_O~a}1r}PsCk;FgM@YUIBU4KdX=?uf4)LA1MITL)Q;miWm zeiHl)!ygd`p?Xj7vkYIMvv0J{l;GzWzT7qzJeJ^d4QJM&c~JhnZS}qA5f?YxGSdH5 z`1rjS3onu2@p~^b{6U>gB0epN{|dwJmxNgQBYFJj|6XPIeUfWRpE`+uq3%lxjd+az zI>YZZd!y$k@h>*~Zk>>#)sX~WVtBB#baaB>WB3wDvn1h8aPn6&yHh{4!vv>XN=o{5 zyRL^OIOSVXv)S8p?UvxH498-=Bv=Vf{gspq=N4Um$;+X;%7J!JQvB6Tx;9k!SkAPk zQVAZ*fp%O(7Qzi0R&$*siW zCGme?IOj1+rX^+L7#=!OTIU;Fsq3i;4m~O@zLNSMk>KkL=Nt^_AtpF%-8ky z1pn6Xpoe&Ff`4!Lh0=)8%pt*lG@SjTT5n45pA8TCh98MY5e&3-9 z?hOz6fK+PCXMy2CfAFLPFJ^eqH+-S+d-vbM@B_00m9JgZ4)bzYR@`t_G^8&qdKGc_ ziOQ0lkj{N7&xn^aJm`&Hmf)of=PXar{{%-ry0WDB(3`;tUdHgCAKE6t%NowPdfFLX znEz$v3=evjD-xW1SI*BxxF^9Y7#{4Zdr>a09hhErKfJ6-c%8fGwFc+2Hgf1(?IhPz zuD{#>xq)(nGCR-MX|cF z=_VKNpB8q72Cufl?#=y#i+J>tE`G}NWnI6>{gm&&d&YV8yw_7{r1_2K((~*a#e@Dp ztTXfnMk)LxxlVc>+rxz)hJ28}qW;+md$}C(%u@%Q{!XZG(qFT7!}^YCV>|7yhNn(> z|2oq8p|HO1(S3ZjZkgiEpZzL4mJ#*Xx?U*1v`#78jXk3rc2W5KW*8!K0y&DAr$FHMX0Xg~LC;yv2TEBSk|{gB?z!YEh1t>QLnM{?l3b*0?#4^I5Y z$v@*&SpbqF&ogwNUI(dta!=p>cMcjbTkrFom+E?*+}(1k!y2m3gS zXQbbq9VNOB_J+++@O_z~zl(3{Y-#_H9%l%m6GGaouECAse@tshL$`vPU{&izabgc@ zR`9uIJl|_J_jZHu%S;@2^yBZ%+?)fUXqhLAd)B@?m{z z2>q?X|EM?WD8=e}<2rFOoGi=gNAgx@2*g{Fxk22$KuIH_@oO8iCT?HjdR(&jw%3C)5maky4Vuv-Gx&)fGK zUybihn>i5vLDh3{u`I-SwsMYju7%=-Z&TYIsdxz8B5S-CJRs@cpeJ{#wx3l!f2@-D z*?1K~m3O!5f^TcHJdV7A@8UZu$<9Yt&L3byanBb;Vg#Ov&_{qyEvi!4#ms3&t5+Vsv4tv~g+r)U5Df z%x9wAxS1a?FJOC@b~Z^%oc{59i#Kt!gk`&ePdyE9C9fTy_BA&J<9*p=@9sa(f2a$? zdrP3lzp(5g$TO~R*UvmL+V!8Y7lS<|iB!*Y&)n-b!+i#`;12htL|+N*^Euu3!FD7= z&AfC@u^QBKCxungbGhxkfdp2pF!O_DR~+;f*aBl9~Ke?K99E=oSl zJxcSUKk{ijGsD5XKd2qS(B-o1(;;R4&VD7*eWo4k@@p-Nc{df1$99u80qqTj-U8bn zwD%lVj&r7bW*#o`I=`|b#T}g{`-0GBXLAI34T|ivXLg~w*?)sg&<12{obSrz=G}bS zeN%d`=*BL?engsnlAcf6b>$Fu8z)~XEl`GnVi>IMH8%e%av+>4LzJIcK{f?WmYOh8D5sQiSOsU_|CHT4`0f+L|D0dNdfpBr6c-Hf0>&w)v+|756n^MF5P4< z$uEd*74k7PQhEp&Q{l^zA! znuaL}JZ{z!kA zpMUDzm?8Z`w7*F9e_=Y#3XQ^YXl)j^kH9V7Q50IbxA^itzvY^Gm*?s1{h-Y$(zb@- z@4vre;O`jtUlaq=kTWG^a^qyoCAd;Xb^L!yan_)@H(X`>A4`rS#??|;g0MEo)(zXa z>>px(QwFr#qy8qE*&o7oDEnEd^ujVQ8%mj+rZDtRuYr$Io2F7)OQg7jfO$`0*kCAW zE)Ba;xqW3?TcwbMir4cZEZoB@vda>gx!_fje==7ufL!ldDLculNllQv1lG5&C8Z>J zS(Jb7&djn4EuXXi^3S5!H?IWluPC;;t~~E82wG8Ud@Kn{L>GTWW{oGnboWMS;Q zM?2S;N@9;XAM`VmlxMsniWQb=(USoG{r7ha{I|yd_b-UPf2L*be((tX-+*>P#QD7& zGa4FB$Q=}S-~UL|hB1zzcxGCMp5p!ZUrzCC!Uv*7i`t0dIfeIuHWt2M#q$X7CiCsB z;;iRUbE*ser&qj?@HXhL!1%e!zlsTOfm$NQ16BT2T)4}><{^(-0AYVG%~2n(HZzYS zXPy@I_eS~KUtNp(2x&j+*NyIFe`Z1SFP4L_Uzd3$=e~1HkU2wj>7}Eob6PF5XIiU& ztUN38iGs*n8GkfaKzoI~dCX4=LZ_<*#uB0)y=F36P4|Wx#w+a=N(^}~5B>!bPVoq5bvjOf# zD=KQ6x01Fw!_!aF9sRovF2&JG=RGA+^3+2=K`)GfG5zs+L->}+quGl?n?>;4weTF> zFz1b{c(NtKolZ-_*Gh1uHui+A2jB04Yt*ytC7S8?8s_A@zc_5w!POqeq~!rWnm>BeOX=BP=~7h6W}$dzx^MZ+SkDwqv6!5%S_{LHziJD!`Xo@S!2%hikQSFKxcHZt!6sTpx*8<9_Qb zIruzfVE-mu?}KaXheSdD4{qrDII_!-l#p+eX@I`b2ET2d(`WhuPq9Z|REGaq$o?!; z>}8-UQGBv@fafgJJE8}L8U^(KR{5qG)7Y2xPfGg&qJu%3Bht$HGI&PjG`y=8!k8%c zi+fkg$w)fyx-P9X{cu{ZVO{XQ|Nf4F|NmluIvrUcsL!u*Pw&dZTlZeh-9GL6_g~IA zTMFd^INJ}@x8qlBpk;gt|1&A>+7V9Q>(su4edbD7!yG^Ka4GKU3&&+v#N&#)`odS} z|2Jl|;>;m(6&;%ig2fYvq$DX?BJz%RpCyLXN%(1ggd>TgNj!d?(~PwDqchQ zLd@VpPK?Noo{PP`8PTKr297xuuO-~+E%7}@@k5>)eNMA+Ea~m%NBrC%-06ALP`tKq zw?0^7#p?*4iruh`Nm0D6aHrohRPlPkoqov##cveu)-iiQ@tcG@{h`H**B9>ejn*iB zvv8-Mv`g^@!ks?TX~i1~pJis@$n+e=4|x&P(x1UGIOO6P`hsI_5$@I*%cc0O!ri)L zr4?@^+^u7FgW|Udck7We;BLL9cNK3Y-04?+qBy!PVc+TZaM!XZe#pzCmBIGP0dK!D;s=!?aHkh_O7RxL z-8yC$6mKcq=|v?WvtfFsJE$ze9j6zSOYzpionBN?#oGvXdQsOZ-d4C&&E-cI-!GX}?AinkX&7BzCz)l~eDS3@0lFpk5$eP|(#=^(r(>Z_O! zs(44?+!FyhB#L(u?$$$lP4N`rZvC_m6z?qDt+%#G@h-yM`fPg@?<%|>S_K%lP`sP) z{?cCjUGeV12VlM_^3$)~`{HxmEu4G6A-yQxL--)2CWBlXPHkG z=kr%XAO1xg*D8LGaHs#x9W)|$dJA{@-`uq&;(dhwY<|X(`yEESuW+Xq9_{YMel|XT zHH=mKh~sn0et+Rk5BmYd`TW%|&ao56A&T?)t6`MuGaP#>&gZXYcHoE6SjCw>s$s-r zJC02hA0pi8E7wtcsPL_3D~{JHey?z+uUtg&VZxoha*#-$sl$bH2BI-vDSn^ubmsD0~U#s6!uj zZ{j_U7Vh>-cY1%&?nhfRKn@b1*VE|%Lh~N2r~oZ%rxOTGd9*15wDbaVHKY)vFr)~i zD5MyqIHUxG`h%q*WgulCId}Xh5Sq7vPNsXsHHRl`z0K zY=HJsU~YiahSY)7gWL$Y2|~R@X!K&VG(ej(!2S>c+GhbqLj$xxOFe;gxmKWcS`2%p zLZb8AU~aF@N5MQpY)|^VcD7L0Ayo`+Y*lUjw5KU?l&_?)$JG+2iqF*`>SG(Tn6?*`>See~RR< z>_%?#xDxk%4A}wM3poNg4fz?u{-s;bV9o-hCgc)Wyae{Nh2(%-1)-fHIF^M}h17vG zf;9K%yw34nes4Hn40w%vlQgfum&m*mF^d!$>5LVWx-qZ6j~X%S;WV#8?K>LVENJ*O zk}d;h%Yo*#7_DV4N!Nao{FtVTX9)HX9G}f zJ_((rg=uxEM-b|L(k}Q$@_)Mfi+suSH#@%8I{x0iSgl|ZR;YN*bo6AP83Uc7nW)n; z2c-S2$j_Mz)4UVzuwS44X2Dlo8DClYv~kyh(5Z>E#n^vV3Iz-OzS;Eft`9<){j`~d z(c4@6lW#STz{IEAjWBbii;DiP25Dt`4~%o~Mk{0wT1>1D(amAzN!*u7?%U(bK{(@a;6r`59;3k>4|yrg=HW)2V;KJ8B|# zs)Nw61(goxbCKV!!Sl2Ihc>3agL;81(|Gp|jOowA!}Ixbr}YI{yA!YDU&X{j@R9dm zm&fMLrDSMiuk|7QOv+Na{~1yr%X8ZOS!x0_T`)5cV>C4|AHu|U-wV2yTv_U6(*)rp zVVazbRJlM(RNCH_rj1rhv@iHBnn54yC8Vxdel?Vm{_cCw=k*xcGp`u7OBt4Bc&Dv> zShh*+fb=l*8zP;x-1433l*2Wm=*u3YeVr1hPr)#@hVP@1zQ>wE-rvM?uw17PTktLB z^;df$eN3PxjI`c)bp=uvdjx1+hqqMShj5F;51%@hXr=LbEn{t@ht?8(uNKwlKMNge z0<`}jTx2bR=FO-RMfz!F)AZAFODRoXmZWKhD536i#G6TaQ0}NG@s0K?(Q&UdS+C&J(0n_dAu8vtLOtPXxSJ@sR=`2JnLAB~uvl8jbS>)kj9Xs6+3+pW z)bX-f5o7iy{J3^C=U+u7R0)ZH-ce89G);G@{OoR@6Xll@i6O0sHba!N6_;2it%JDc z8>6``-czE?iB_`6f;fxx^f*Em)qAK_8P$7=r{#S4(`q#(B&9K2OkIEf{ZGY!^qZkl zl<2pwftDaf*AL+P^xS=KRq*yO_DhZ<`z73WRRk?m)C3jJh;!=PT!sH^6W*MPdP-5u zg@N#VKaM;<4*40vd87RHUg2#m+^2aZzLH#MJyd{3X$`62GWRHlRKtab2|8De^ zdkj*axCVZ%^rY>oXzSKO?ePYw1M?}$;Qk7@y9%z<0B5L~cJm>u(;B<_W>wtBbx9*V zqwHyVMy1W;Rl}apn)488#jNx#NA5U$D649HOW2zlO5! z%5As*!L^FJ{Dt2yG&2-;`HLHm%%?cAEBsZFl%HAg%)*&#An(C*Md8UJT$VLSTceq4 zJAYKhnwgj+oUN=i#USM&JgBzH%C}52%Y-aG7TZhgkCz=k zc>hzf*B(uUWVb(>ikc*UXBoVaC|@mTdfe~)TyB!5I#XU#%DelZyub0LlMh!z!?a4@ zS;kEEPdv?}cskmQHsAQz$!VBQX}2;`C(}NkwSlA;rj17a>MbDCyqW3afBtU@8j<`C z@SU%6zNM3@@fjb+#P@$a>aeK)E1phnaNpZ!io5TYJ6xk`{Y~O~bKkAopJ%+{?z?s4 zFvAtkChog&q~40>6z;~UIx9|{q^SMUMse0dIFGR%{?}4Gzi`)1$*1_$!reYC7x7$C zeoI z+&`W#$9Z(EQ2B)UA($V9@Lt}x8)hDvCpAG5=X+uep$fDoDU4U9KgK3&I#sP zy)(ubo9*FSFX)r~8Do4hyfMTgh3Sdsl@Uft^xo_b;!v@-fD}ewa%!rMM8d|KoiK znYN>qv(w{yr}V=x7gN3tmo_)`ZnH$$@|x4UydD0yFuIj>FF)s3%UHV}{!x;=|F!Yf z8hUeG#2)t>FD-sIk`jw=htJ^R!^MX7hi{PK_$zy*ydQOtBKQUJ?eM!}ENRSuf27renv-MQ9^towv)?cy^hkIN%oSKE8@-Z> zvz!Y|df6ZPg@nHYSRV;YT=s#Us5t8*fr(+|ZR|avctPP%rvx9QcwynV1-!fB#f1N6 zf5VHrS@AN$xyCW#S@82MejIC&WA3Wr^@Jb8D$JPIpm=@ZN3ni6`hFB|DEtW4ZN~a)iZ>E|*d7KSsW=KV zgp;cXW4$!R*>f0}L)fzgYuzi}O87zS<^nwx#oG$!iuTY+P@MI~!0gBVFQ_*u-ck5I zyAS+4lzCXEXMMSg@V!`f8U5Lc_Yl4ZD>6ghNb%mnciY|IA1U5nI9J)nOl`%72>;T4 z3I3$w!-aogzW^Vm_$c9@TkgZyMe(u1cUtb-c!%N-3;)b=pT~NNKPr5?<$jUH6`v@4 zi`@dATXA-+2WGRC{VNrJTDaR+`{GZDc$*^J?W=uKarPqwSP_0B+~1@44B>8{?2i?n zDSW+M5BqN_K2NyYKYO;~^M$XqYhiz~;%^9FZP$R`ulQTSSJ_qI{S<#!c&hBfojt(^ zE)l-mE{A;#n?~tm;CsT|ewjc1nBYr=yZtgZC-{I5gu8t%XM#uh*b3nb?LxSJdxAG7 zPj6llKEmf$(C``aq43#QHy!#+ihm@0j_l{XNb!}z=VFz0mPpY~k3b-=aBrR_s$k-q5G34oGjigmYIFYGSx_ zNWNQmY3%#JRUQ(2k8tk3g0{QjdxdjH7HSM6?4#2i{+7f3N?f5K!S@U2&Mn5geKwKa z4hZLtFQ`-4MEJ?GV+9%V;@~-O-W}mQD7=U*0$xw?L&A$%44s%xihm`%m@NiAT>1O8 z@T)DBH#1{l-}m=4Coh2Y&&i+h?%V@^4-3y>bAT^a{D^SwY{Na=TsUd}sBrFfgB>gs zKPKF*-^@uOd@kBY*8==?>pd4x{Dg3~K6FjRzY(6#VtYYzr{d_Ug*)6)2j!jOr-XB7 zEbLdO__x9fT1>GtXTM9lm(#+zdk=Nm67fS`A6hcx+q^sXBK&8BABL6<>Ys|kN!UMv zAI7jk_q?=^R{?$$Kg_OE97!Ae7=F;jQ~Z13Zr)3Z;>glq->rW4o2_IE>(Keeqt3Ckc1!kxy1Uop85)`4Yvs z?rD8<2|x7nDV|>VA6Rb)e{huF7t>n?;dp8siz$vF47g+QhrV>hGYNO|xOyv|S-4w= zb)w>2_q4v@?pRofO!2J3xnmYIvlQp|Qy=<|4DWY}Un!jH{h@aY4JQ@0nMet3Ev;0o>!?@@8qUz0I!?GfAs@^Kr)U?-g&L zcsgXR{2u8}L*Wgus~PG?ir*r|hw!o3{S^JZiuV*g4tq_ZpHOke?>O_2eF(=cir*uA zJocqSexi79;SXcqFVr6t?<4#X>|$rkY{mNupMbp~p#hnJg#rq3?%sz(W zSBmq!jx&#APcN(;t@uFU6S21;^fNLi;%AWXN!YOsdSZ$*9gH(iVsA>UA&*9v&(E8a zk4Fo-H}aPT-aa-_8#6?>%g5R(K2-6dsGNFtQkkB{n_c0q5dGToVJq;KiZh*!H!Z`K;7t{0Iva0Vge|~tP@L&(ylECT1J9{A)7f~_C~O3t zNpYsL@up$e5c~idMN#}PJ&iY2!>Zt)Db92=-drDE558J)rjPNaTv!hLeZ`p$#&h@_ ze39alh5r`(7C^gK@u!5J56*+%toSp+e+qsAudMhK;b()h-~|+aPWYkV5O^lVrwTt9 z90dOjjl<}9rwcz28~{J1_>02#2m8U-DE^Z09l;Lp#fr}qzCG9u{*vOegl`MBflpF= zw(zaNR`6@lsE)!jPxw>8Q{Y9E{a1xQ89WJ|Me+Ho*vG99?d%;^M z{-*Gu!BFs;ioYd%NH7Gvh~jSx9~^K`z4VH|BYaRW2>d&A7DVyzuJHarfAC$3FA?4+ z=mY+N;_nIX74!n1srXXiJ%gU$k1GDY@a{o(@a~E)6W%%K41TNP%Z0ZK+JRS5`~%@_ zgSOzs6kj2{RnQ7NtKuIDZyq!U{}r7k(er*JJUK`PKdSgj;f;gF;M){W72XK@UAceDOUTNQ@(-?hwAjG9A6C_)g)AWp(#Y6a4_Gp9^>MI;9@*0 z(OyeECEV#KtycWBaHpTRMDg#0yLBa=RQ#;)F0wx1y^5a`-U+&9sBb9#qwvxZCB*0ik}zm^cFKIenB{Owa|V{)ZbDs3a555#@`kHMYz*{c6$_ImqTcW1*RV4 z&(;9w2;K>j0_hCt0_h658`1;P6N24uq2m{zy&YiYaDY~KfO*9MbeRKaqy^9c3!o7l zU}kcFd7}Yl$Of3z8eooOfLW0NW?BcBbs1ouY+y!1#z4kG#z7u}jE6i7c?2>6@+jmn z$m5WSkV%jyAd?|aLY{&=4S5FgEMyAgImq*nsgP-q>5vy7FG6NOUWU8^c@;7r@*3oI z$O6bh$QzJFkj0QUAsZo^AfH0ELAFD7Kt6+DhBFq+574U^pvN&lZ)AWO(*ed60_<)P zVE!(23m^v|2O)WNIR*I^avE|5@*U(X}e8Xn1RgS3Hk@}jvm z_r&%4AkmyV9wXgYnz`;J_3iaNoF5eV!DD2Oc*J;o%wN~+eK2izFU~J_{|7M2AKvce z=X8(H7`bz~nPHFYXmeyg3J=2)nR#SbqI0^b%?tz2wO`Ra|Bkznoy-VZz6y!3^PKKf z0gL>*+zvVKzf0NCEOMLdUp+(Q{^iehdHmDfQI!95cNqNS^=ELL1EKOc_dkl<;yz7` zn|FNJXph%+UUp7)Rv-vn<4aza;ds=Wf5nk@3RHsIkUo&fkhdTkAiE(aAr~R(ufy6VkP?u}kOq*}kdBaE zkYVb40?d>tkXIo~A)i8Mm;6g_=K1Av0_;a6m%RCMdpu97{Ev2{`~J)>-TgCuIinj{ z;chhuMDaa)V@ z9YTAr;`k zD9FdSegu-PhBf&hysx=GKJJg-`Qsxs-SsX0Sf-XcukDYVpFo+5^UIGHOW8CY*?R@{ znoq*GJdUfB`4G&%L8{+?xT}qMS&(LsJ0V>ly&*#&qaY7MCPSt|W1kVcSXNPoyI$V$j}kUt=W>mgl2Zh@pg?t?rHSpey92KtSVl`s#&k>S|_GyOT^ zj~Q=t=VfuM0ci)}{E;&0(O2osPvaQHFOO$3pxui>c|0w&DX2+D(|XIcFiq`(NE>)- z_<8t6xI5evQeTkQKC{cAu7FyD>1v-0*egIfBpBDinHq&*Z`VQy!fVhYRTVDm2}6|n zv{zrolX&-|sHboYkLDSsw56UF%{QX=_1hnu?Marsdc3b~_>&KBSxZeO+N_HH_MzV9 z7|U^8(l78tYzy+PC6>KsG*t~tp*?`^F4Xkc?xc1l`Iq)h@4_RNEk&}$mO6wqt+Ugh z(m+#sn-5p%{uH|>pzbrxo5KSk+h?@#v1nS-w9|G$9}rDz0**S;G+p%cXnM(RLYR1W zg|K4S5}_hpWZ0ggX@hC$pR|D8=}o0=OT;;^wy@N{rRlic312e9^hvNW_!NC!yYSnM z-yZz-qtEPMz&=abZ5guHh^G63q?OM1swQ)ggqS2PXCL68qrd(}?|xGowb!`6(^@?3My%=b zy7%cvQyI@hpHhSM!G?f+ige*9dJ;KqJvuj@N2pl!JYYytWrTi|2w1 z0d=Msn%^vYS!khtkR9gG?@^=V*~Wp6I;Y!QBmkns8!h*ggL zrNZ1BZJI%7lRShr34a{HY!J!g3`{j^1*GOU{Dji15>BhfI|@ zn~9x^-i4+CwGh5UTcHxP=BQCeZM!Pa#Je6^di+s~j~ae8pcTj;wFaqCNNq#@sEt?$ znu`3@li!UPKbe3rg~u>XFcCVKt1LBJ*Ffuat)))vI_TGKvee3@#xAvasp(5CU}^~O zg!b^~&@BD}TE|~PBbnODyP?Uk^OI=^uSY_E;M^kdJc8+H<@=o@I^sUgePPFf7`oXe4oW37JFZdfim8aOM_qi0w zK4JD3vlUKTbn`tQvhAj-PxmKGRexs_Th)JEQ!O>;>Bmt!(}#PdDdg`sW~dL$s|ziA z#AsS!*(XY0dIl4Mp2s+c0sa1V8T61d23dmCfHBztvpTkgJ$+1$wgVggV@S`zUB=83 z`yPIKynnxn9yWd1VA*3$8za$wJt^RL33;oqnE&$UnPNWI{6l6V@aj3sep9g*a3%;t znT+ue_GZwn2I#|RAvy@O^O%|F{lz|5{#%X(95LX1dyunnw1oFH#MnuraEgz;_LjYm zbRk!8$$#Gs?VI)ifBjCo!N>g$v%xpB z2mgfz3DWy4Q6cNY;5XnbVhH|1fNs7{E?bE z)Z(Fr54C?@L4V9b^t~)Xzsrr#Vi=5(+-L0+`yBGJ)L>n}J}-vnM)Y(w70n;|{Gusk z+51QT-Z$)@rD=}e zEJqe;Y7=I~Gt=~}q{;hmY4bvHN<#ju4(Jv)&q8`H$7xI4#KN_ z0*=7(>5gOEEh#JlSNL?jF$&7QL0)NMQlMYk*+18}X0{J+G27X{$(DAuH+8VHy&vN( z=R(krwU(ndGz|_oo<;YWUw!4xUn2dnzf^3P4Bqve_AzfNVyT7BkW`26MmxLF`_;>G z77y<_Y&kEBri=l5lxbRJa`+G*HJ^FYMUw+A@oITXjdzBm2J|&J8bvxZ;CLrZ*N4;y zPgxv#WqJ$!M1{b!_QmJ|KNS8mLsRM`&)25@}Ob89N!eMr=2#|nrc4AM_SI# zA^Y5N-VjZDEk|@1nufucVDtvx`LnFYM zmRZi=;l0}}$8P9D)!>1ko`0vSf=vO(&}pN0*vpqJD@3n~cKf5hmb#NPvp!PB`-;^g zz3DgenveAima_+F^Lps|aAqD|y&;U&dQ3Hg7P;rT4t0$a!8ZZ53>arOp(W7EPTFwsOm5R`<;LJF>Yl64EDSg0MhGZSWc0MeD<;)G0O!8W| z`YvV?v6jaA*?POd*UwltW4(+uGSIlw&uYp0Bp zD}AcDWPU-4q@A108Xw~GW{v;8O4&6&?A}s@I&ILap7y1c#_yv^Y7ol5m30>`B7()%W99qZ~LgqF6QLm#abYga) zrpr+$`Zmz~5M1p;liN~vfxc~k#zGMG*y^4sF8A&asbR@C@GwRT40PI#`)AB*IroA0 zWrHT&96P{2Q!6{br~S3TZlB+LW_J5n&k_{%_HMUD{d;@Pa@3dMsvL|8sOiI4*cDQD znsfdmQ55nsH-q%cZ|D?vg?@bvkwQLyE25tMQp>5*U z#NcU64)89?z9`DOrhVvrHHd>C{GlaE+2ZO;! zoSE%SYTWX@KY~J|4|L9`aZGzpnS7R7>I~1@h`%LfN-Zart2TZPphhXA8 z+t61Pt-HF~a4ec{e+7CeHlZcC#WeCM@T6(v-?_D)c=sN&&5t|x7Krw8M%?)jM(s{v z#O@4==bteecL5`DSuJ(E>F;E-!{7V3r5-xjG(!ypns%5Eyl+37T0WiTvz$-IH(Ci= zx|1xmV`#Tm@Q{zS*DOck$yS=a{{GXZuMcf#`+9qGEj55>4|+d{CA!(k^n=#%&+vh~ zf#uwAnoe43FEM@|2_6rqu}AX`^z3!=el0c}=Vw0t5&TU>9d9-Ic0QJPJLuo+085>E zx;NEO>wrG4mRRMSNV-@H8mRMqj67`T`_yg}bCr zn!L8Ff4(`EYgrWltqgsY+Ce>N#WaK_O=D=^G>67cTWI-of@V-pXcP5;2GSsCEe(OD z)4kA+8V-%B5kX`BY;PFqiqQYh%%?s^FPO&usgf;cn)B*G+sa=(C9}QBcH34yr&<+o zrfU|k>6nMhIlZoB9+mhTEX!xk2IqadY&!4O5%XlKW7{ls4tTYTdD6$yILrCqWM5d$ ztfq-tG=Km79Rq(J1FvGzB~#($>wh)PhCKls_v`<;`N8Y1OmGYx;Lptuen)YB_sr=r z{AOk{n?AN+*k*@V0K!6OvUA>7RmemW7JfjNb{`DYWr84iU1&RoLXJhqMr-hw=& zt^>mJVs?wUw#=J?=HyAxf8b}b6rBELFu|DI!reT)y^7}%?&jhBp?F^5ZXRASG{Wc( z+#i!qI9!MO6&1fqxSNNUJMmltt`_d*HJ-|vi08t>-8{~wiWe8|<|oxtyp(V^Kj~V< z%L{)FwR6-<6|X3K3N&L-XUm-Mx3X}j$23pzYQj6C#|C{Iiq{mLVp4E?0P*ABOX>~6 z+o4AQy|Rke5#GkO0dJ{zJ>hPiM+3!g65iZ4hy5yw-z@wNdk1(i#TyE5W}AWMRQwj< zZhpycNN-U%8wszEUOUVeR2&5d?6~>&yA^LH+|9GUUGe6^-Td#$inkQ*=A&P&cx&Nq zUh=Prbeq~%cov%l;n}75oxqA;aAuz;Lbe7I|xs*N#L~=?y3rJT{eBLeG%^TjM_&vhizC4>1?{2}3PpRYZNj~DLt1>30j!@}J@Vvpdvi`;)ixLbcPU=D^HJ;2HY z0aq=;8gl{01*u~b>0bRa^976xQy+%90@R(M9zmo#LvyrtVbV>=Lm@@H(0+NCJMY1K zB)CB#y9JC#>ht_7x1)O^zq{bRNQZ%JBF=S~`5cr#TUT*D?4E+0hEQ*SYqxS-K00!| zo9EGyW9T>GgD0DbBge`&;+Tqicc}C4VdhwW{hOWp_xa;J4cz&HhS0}=EP*VCFbvyp zJOrVebf0csb&I=pFOCe~92~WunQl#-r@+jxY{YT9H=n?fZjp0L|Eflb^L8+6x5laS zSuihx@JLw!*$iPkOhnZ?8tXr8SfaAz573HB!kp@>WlV^KUveAU7X7eqrMkN1-Lg(3 zvJYr~jzCJKslQ=bW^H~L^f(_f{PM}y7?$lcRkD$Gz^#_r0koS9vlVZ#YmlmW))VU^ z-fNh*1vpD@vs>otytkQUuL?`>Ip{IxZ=TGM{t+#z`f#Hma{D__LNrI;Mhn{qe&>PR z7i1*iCAo+8nP)7;==5^5PFCT!20c{k(QD1o)LJ$w1G_*k^+Al|PBJfjQuDXI9|)z2cP3tXjWb_%%{Z(IxxHq=CjftAPl zB^B`Fm(8c$GBuJj7%0mOS+it;oYks+6uJGwG*;=dZo?geQ9X9awq*8 zC+l_6^pM#N_wmwY9m#%pTkKU%WkI?vh?H9jYrM2$kAr3T&pVPWYYsHs zVOx4r3(HX`#>w+|e<#tO@dw8BI(XmuN!iFdF35VCGz~IbO_Qb}rlhym$FM9Qd(5nd ziSK18QW)3T#D^;5ST3D0tumdlZbn^4)1-z^v4si-}#c^N-OLQ;ae|i9|V^g zG1e)`jX6~<>W>h zjou#LaWTtw5nZ_sc@am17|OQxy#EgF!Phdv41?=Tt$!fb%>$h~%_;SI4(@)Ob$ zYsCyvP0RWgP4f&}X8ew0k|uLouGGsb;|=SwG-a_IOJRtaOLW1zr4|cY6bxl&_>FSH z`#uNZXC03rc@<%0eU+}elBl%hD!c5(aW3gKYMGb0{mb~4rXb|Zjrlb@9UA8=>zfSI z%Cx-}+S_}Pis?t>0^4NtpU?ci{g0&vQ)*(J?_yY&9i?l|G(M1V!&qm$Pgb1waZjB5 z_&-*0zG?2M!S-)&#aWVZrFgcxn=8(g#-4Gu>uV{_R2%KvQ&e%5H>?A&7LY^njKZ(P z3iU|;if0m@O}@XM&<^*{J212Gtf(nt{8e%0I?Q``+@Lt^QOAz=EmNG|HP>>cKd&jy za8T=p;hL^E!_88Y&+&-jlDp$u<#P{L-1T={Azx%~#Tk#(HetMefajGw;SZC_8jr!q zQxW{{2>TIdKLv9Mrft@ze?|RoFd9{*p7`&PthYg@HLt5vu7DqB@uBfsD`u#D#HUV& zXGo9d&WO0mjQGupcXB1J z(mhSNH_4FmKT{2_ruR{;mG&{_|PVnPjHtn z43Cch|4rF<-}#XEz2KV^ci-)R_#p6O*CgC=-(jD4Kkx~PyYH%J{2p-5Pr^a+HTRu# zi{A~9yF!Ay?;$1L1^iaUT@1F5cLaY=xpTEdYuor;;APcw6%pPt-Wt4!vR_=>!OtjOR`{*)+rZl^evR;(;|;-kqwN>RYsUK;SV4HLcrEY;p$m_LJTLq0 z(8`Km574Ygf>#q>E?$AWWP;ZcUN~M1{DU$HUQc+Qcz$qHFw@+>S$GhSgZEPQZxen# z_B#rUVak3p;iqHYgO^wSwh?|f_6_)bXs5$D2|xRvpluS{55Bf^f_D+VHMRr%Wo5sI z@b$5c;5Vu8^b!7U?0xXOiVqMzC-ySnb>pS+z%!SC;N?% z0%H@wORMJ{BYb%5e((>9C+t5WyjQFr_&Lmvh}@Ydyiu$P_#VY43vUp+1^h$BrwFeT zs}DY3@#(^=$8G@MrNTK&_%*TXz#mcJc|~~M*wx@euTF&Lb>Z1#xxp{0=Xz6khFCW6 zR?3|v!q0@?qdHetx%0m8li|1E8k;+?@2=brSsa*K!p7h)DEE_uSB9Pl>OJatGYc;X9Tc?H6h~o$zk*?L z@U_Z)6!rMK1T6@Zlqw$b3;#vd4S8RM6G;GnKS1*Z^+m;zCE)KgbYr09r`{v7Qv4l; zb`qXf@yf#Y1z&+*!n~vC{UU3`-xtu4#a)UcYsBAHS?}YhN}u(Fe-dnl{WlbEAUqX% z=tw^*ecmqoz2F1z7gc(`L-@krE%5JEKGRb8+~8&KhAN+FE&PSx1@L^Tyt_;IWLY=l zGZmlhh4&76!+w3tk&2$Tlkk)v1$>UO-%WT^S#KhX^0%k(+Ce?opR3}hukeb&b>Q!* z{CS}8@PTqxbRXz8SpX6{wU!&gS_BRs`wcr{1Q|~P~TPI94GvY zJ%i&+#UB>_jXi~9CH1_I3O_9C$PZHCnJ9dptmpo!;!g_y9GW-K`BnT`;alwv9MSxa z;(6c{;q&c$9M2(<`TF#o&k29UzJlYcNMybq)to%Zyd?a6aMtTFOMcAr!e`o`tlwQw@fU=<^}DMm{-SWVes=++^Con%(pl{hw2e7116zD6y@=L&zvzJp^i#a|ZwmVFDyY>K}s+^xs4 zIbXux*Mz(E%|BFpfpE8;_=?1PNnI@b8T$;5a}{SelKeVZ&nUiBxLb#7wBpNzkCpYp z+A98maJNobeZ@Z%?$$f2s5s**3HogJm z@eRW7wfEx4`JK`G`b78;I|Rq~72hP>t^4+};+usJvV(AZLh-G_-THC&E52QLf7>6& zo{E1ayr1odV=Ki!7v9%0zp1PEm%{I{_uyCw_3$YCyM(*-k^ewp5b@o@-FnK~72hM= zt-m}|@x8*`dd))>-zWTQth9jfPsR5O=l=3&VJUt<_#tx${7cl&qwpLQeh{lSpkAu@ zA>jwGvIFYFihm`1KURH!R+Zvk3*UzoAyD2aepvWktQLWBX_Oa{zej}c!AcU?mqqcT z!gphp3Dox#KPKF*huc;06Hpdmi=4$lq^-e~wixP%l;dr0|_s@dDb0 zik}kh*3;>(__xB{dOFn6t zzE54nL*Z_HpMr{W|C}U@uq=l=`%5Ik6Bq8*{aLJdl5n@~&x4Am6Ylg2k`?DZKS}02 z{E!bQo?f_H5Bf{g52N?aeT0&rS^F;R&s995aE={fbX4(7!reO2brsJn+^vJ0Pw_0m z-^7YD&?GFD@HeY)x1RC~if0q<)?e4k-gmlE#Qt=^QVAEuTT&M_eLekjiReUgkPVI*7evcjLmDof~3R-EmGB&@&m z4EQBge`C8M30lUTz_TRkpQ+af=Pr^c?{X&Mp@MMN^BI_K$X>cb?uPV$aP6sH(wDuY zwZ+JfTSw%t%v^)$uk5UWdy$=gW@aDy7TEh5a=AIWm;BGnKj0qfyJTzwof^oska`f> zzZ=I9kZ9eVi7?Ml=L=!}0I~_f^?P_v#G-q4;MyU`IY`(R8WEIht%-PDoHv7X`X_u0 z_~gI1#_+!fI~yU|-(5IA0r?d|J4Noa<{C&XNVMKi#G?ED>^vFv+e7}D8~T|U2mN4o zB;*MQ{eQvVyT)^}J)U97XIXcNZfA#?_wjlOm}^2V=iNMu+=`y@k<0k|IHx-ir$1!T zb4Gqe_BLL2|GyK)%fs@YxhL|U_gwByx5I8to_`iM|5f|+^8%hXshx}8f96jmT<3eJ z=k4h*^IG(NqIdB>>F$45dKrjtkA^U;Q~u<+{wm$A!#&X&Ta33ayj!QdTYtuKwzsA< zB(hr_W~S>tm+=ue=l4T<92?{sMS49hy>?i{7vP?+F`mdgWhuKOSp@$9{~FiLfyP#9o_L} ze;nnHv;A?kKVtJH^AThnCS-Uv*%KBpie@yYm*Kk}5IS9D`$Xg?vC#nk__n%83B0)vHx%ORgb&OtKwMEZf; z0O<&M5Hc0A9I_MgGbCFtgdfrj(g*S|*nd*C1BHb@u9D9AL(639Nt zMM$3Ba0}7`!n8yEOUhMvzZ`=^jA3@&$CaI_fZdKkEL3|8S8icn2m5}HU}jWD>~hy9 zUbB+37qhI-p&K3=Y-cd9lC?peO@lsE<&bSwo^3Qm?3~!RD(;@*c3cf-T4{ee%5i0C z$8j8pre_U%O6c3yn0em;eOEo>L$7z&uCWIma`yYgJEE~q`$G+Tr07dq^g}&lJJxh| zj|ZhzIvb-+skP4ZoGtaO(@@G4lnyEetSj=)XP~WfGGtFJU0iKS`B=zpOZhMtwiSIC z%31cXF=iOHitvqLJ%o9+*M!5un_}GKoNhjf)gj)tY(??xO_R>P7qHKrK74Mz&gV?G z8TNCMt+cn-MC}zO#`xoyQ#VCcn3#o?FW!cSyReGD(cnAG;5A{Pury}+_X-Dv&xfvmq}uII2j@st>D!~Se;r3?0d(pEk5x@B92ZqC6h!g6u8%y{;?v9@H$ei@$a z#5~z+V(i^w{Cow?x%PI1?G~@?eaLJ-^iN(X;20yrQYV&l%)O~5mi>}+=Po-ObMKRC zIU9XqY!{Kw;+mpywrY9yHgt9K#`?n@BxzG5EF0dA)%b^m(?a&|)9v-9EZz)F<$|(T zIW|N_S;*d$@j9B8$Ot=4d(AukO>^C%0zNf8VAzvg4%e~P68J>C=h=8eEA2MS={{pC z1xte?!5_h`;d9|@;c~25_Fb4SRv~s4 zw(y>Ca5y!b9ljl|3%6rd;_>iYm^D@~Rw-61c4Mq@tZ(d-SOLT$-{Ir2r7@02(e>wK zR~K73``_;i!Sw()7< zml!n+Ik#diRy+6{>ku5lngf3z zFM@r+;ovmp#s3ogiuu?D!;)d;uu6DK*drVejtU8|idcrrW{o(VI=GRLyVa>R1R^2YMVu8CEQRgcw)HHbBgHHr<7-4`1Xn-F_6 z_E_wh*t4>hJ9Z>?G}9 zLhNGfmsl8&#q-4T#`DDs$BV>^#>>aAiC2nOiO=$JP$ka(A;#Yl>`%5VWUn#f?+{kz z>1~_EAN9Fb1^Xz{5bbTl+70_{cHGai5wRHD<`^?$d6{7^J5$IV=v(KAE9v{93qjMz zGFnN~6vO@-y0FlMc0kD9I-aFM_cJAU!{?v*El2fe|3lGdq3N)UtkJZ=%=Do>486`l zwr#vnRcE`3rQR09G2hmTb7Y+M=SyEdX)~mao<0VO#s~V8k=1gH3{@iYisYGGJ0dx_ zE`APallM1@-Q~lT*Y5E?)w0xk;ME4PuKitVt`(m<+L=1ZXf&_BCjDxB!grvv+$%dVoSrdUOH{TCSrqRq!GN1|wY%g*(tios!T+8R*rgIBkU<`PZ& zO(yTkMbp@uev|$yhT~P}X>SRs4IysI_&!ZbrH7g}wwjW5ZqN$#NAmAwM1&zt#yH4F zN8JnYq2)f$aphfPQGVf2x`TjOm(5CBYH!;e~xGh(e#0g z-O{vKM(t=?Y&i}{(-K?5ml>@r`<&?GRICuNB%}rjZM-5nJ~ZtxHGFKGGs}G5J`p7? z$NqW!aB!bDtqwU0fw8p!yBJf)fY)CT?E#wJ5Pct-Hkq+Lo-Ucy-efFw_^4g_21@eh z2Wo&##5nDCtmp6z65@41-Jof3N3bY(Uuq18e4XLEuQgob>kY&HqULau)E!t(d>Pvl z+Z#I^I~F@0I~_Y4I~V&k#=b*7#f#8XK5W?o&a-9E3ZEacpPXmQ&6W0WjJ^9jTZI|% zSSJQ&e2O(@hW}E&H3j_}IcsM4*!#oG@XvUyrS=`~IAZShSAQ3c6|(7uedcuiJ(Jnq z5^@B9XCGlDhjKx(uWNl_lD%u?Wj+G$oM@?)Mbk#nSE6aB$?Ib~w0V7OXR>X5{jaE< z>P;mqSN7!{Wi7{M>0=5~^f;RrITBO&W60y@A#b0Z>gLxpGPhxkhz_PRN=v3Frnn+V zU36onWxq4scm;E9GQ>Dq!LtwXrppJ^>7%Vf<|`jd=gn6>lo{+}K9t$)V?H;lZrNMP z`=?;7htz<&9O8>;?a;Kqa9oQvwqe%8gcwKrSU=kfz5nKRfNdFX;oXnhXZ%-xmHo^= zdnwz(`&89(9Gfmqu+QL2WUVWAFfUjfEW=8Qn*wUh@an#xg*P1wsCh}YM|2WtI$$_@ zPSZ2?1|NI7Q38I4vaf-!3G9RRe_wlZe4UShpUpZS!t`l#D5l!c@d~|M><-2LaEn&C znD1-)Va80=;0$s$KJy)z1Mrk+e$mf&MF*0mgQlN|f0=@Aoxv&ZM9pPuP0?E#yJ-&4r+hrLF+4jYX{)SnO;btR z4(XY$F+IB<`{e2Gvsh~+dyJZ2v^h<5y=Z#faFmEP7D1Qvhk!Z>3_V*0dtqkT?b;iz z?em=7>vQ>(;K)%IBPlWyqdjc8I^SXBduQw=)cQ*K8eeVXfGN;fnhZUsxxUu-32J=0 zz8BT@qPm`|>A8B|GO6Ra8XoI+*-^8*#@Ff^#d@JuHvzS|>8QuOi~8GE9% zkEQ{~vUrB^D_bz+NG;Dcn5*%Onf;r}Wj7XUinO>jp4_r*@cxPlh1xKfxp%6v~p&2#=6OJ|?+ zX|i(s!57^dm}IGINqf&2jvn&gqFSn+p zW(Qqq0(}l@B{PJT;?de$3oJFZ$-Xud{I~a`XbUhLpCLD2AA8E*bzPj=ZnT?fsAof0 z+3!&w*J*nXO2e};&IiqkvwC=wuUpm=7Fw?2`4(D(?_gaOt{!$(oO+{l=~dA{rfIoZ z=>7l6Ec8!wrR)*J(!;g>C)y=bU4GWVREcpcpZ~SAMrR@Ok+Yd5!OB;(#l6@)M?c?=~*^RG^&sZmD78Je8xzZK0Bgcq# zAN|4%R^;QfQxWYIj(yUdd6;LqFyP2O&sJldr_U|dWoN9owpcRSTN}~3s)E+k%VC0(;9US!4?=$Ju$; z`;Qx_`slW1QK+c`}!5Z{!la@b#8c-z~q`=zFz3 z=bt6Ig>-#|Xz9_-`FQ6ikwQr4+QGhr`_c^dUu!=5gAd0ImKs$IDRbWOmU_UvYpQ76 z(**q+UlLeLZ4%nuVoKONaq67Y#%H4C!>{823In#$8po+e#gMc_3#x>Fx+yV^YV!V$ zm_gXcQWul=uQgdaRNSPG0R*;%`+>uZ%9Po|9- zm=8HG`~+{C?p+r&^54c@)DzFeq7|r$#CP~|rIKw9ADhE2_haQ67+fENYiDrIH1|;D zeyOeTYb!Io??gFy7y69aqYtnHdL27rt-}<2*}dgQT`uZ*Q3s6rVbmR?UKw@HsE?CGGdPvgaGU;l>6$A9+se`h+O=8^@jKPx?LTve7m zN^HGuK%c-7^aossb@KQ98Y}JJRZC0FfBHLH_JE+NhNV_MP1R%6Q>E!eLk$K#%gb1C z=155WBA#tBMeVyWYHu+;?Zyh1>^~h4ryd;hp<_rRgKhgb=hx7kU1mDm=AD_**O8xA z{!4#P-R_<`G5_Z(a}`|dl*`p7!BgokR(r<}y}ODt-Ev*Hg7}}TI71iB7p$+i3v3S2 zV}0#5^ov7QLD>I|0??emKl*jG_(D@bIj1QX@^*JMx1pQ#oAbuzrO_2>rhVR>f@qaS z_cVoloFGr!;;$A!>ovOi2%O{9Eb<&Q6_6O9iBJ9a-`_FtzcU72$735F}fqI$Dp47ZUqUFO2y!b5w@EsBotjHecBU~mHigN-Fjgq6>lxv>3?0N_+7%C z{uf7#hxaJDqPXoml33vN%)>Qm$;RCQ51Zu>JFA?4!>qKCLSMg=S`=OT#tsC{e zRtWEF`r=qX*-sVT2X%V%1S`HqcyHM!J-y-^gu8vxFDdso3hxE2Md;h+PNe58!h1ra z5$mWZzFl|^XgfkLQt{7)-wjPjjL<2*OL%u^Ng_QfzE5~JXi#F-oeB@sZ}8U@Kh#T= z{lmiDI)GW#`-KsIo$*5pUD-b=JjJBoxKFw7<~url&n3$K_hR4ad%mLh&%!&P&lWpe zB>2Gd!f(Ki9GG{T-~%oSuW6W%7A8ma4f+4TUxZgP%y+*>-7$_M`LDvuoANmRlHdb= z7hcws#qm9qgGo5Te(ELRZl28|#s3gK)DDGzuP826O5^6=yrj5=J?yc7dOh|5NB$PM z9~0iqcEge7X2jD8?`pf^_^fg#gYYi43yzN}o>_Qj+Zjie%aJ=-g?F-@aAf%#@hgS1 zZHFEtq}zz+5YBcV`b`u^RN;?pLg)o3e-Y*QbL%-Wzlz*}SNJP{b)a2-6>&6<@t5D` z$C3F`#Ay#RBUuHJ{3qh*?!sSQOZS+cL>vt({N=XvpZP|_(OkqI*V(~}HHxFt1AkmU z$>jr){j$PyU>zIxy+<4!R`|<~wRSKMK)Hi%0{mTR8GrnKBm3xdz+X13^y9wMh*uS! z6>C$u?=j*vgu8Vf`Q1hQ2H}}4-zUGXh}RXK32SRZXGq0=ec>6g>NeI-Qv4R-=`7Px zUd7S$!k?R$vs^vb?ZVwWgXfjMjfJ~;fln&lM0ji2zxZLrn+k7bTEUl5iYE(ifgOI3 zt1I42xZCfzm*RH_zXRh2SnF8v=E9p{R0rjV;w^+X#U3!mG*!H%aJO&rEsD1i-dNh8 z^%QR{{C0CY+_^&WHo~izD&R+uxT5#cR(MHM5`3xRcM30LSU+8;_+7%?IyTf{%!PP*vb{S|zrvA1 zedJ3x&cZiD5&dLjsD&YAAypuCAfv8;?kkQxm3gub-u$aS=0`@%`)m3m`_=A* zxfi6rKR)V@)BSOQKW@VDGiClmnXf}ePB&<$jWQ2a=4X_7u`+K~=2Oa?9)&>UW+`ue z5l8wl=d$zfaXt%^U*|v~ec7xiEH0sdFNtG0$iic&yFe=+cJKA}tK&SnuMIja zK1PFweHxr$%F^#+G#r@~-yyj?dloArZ)XdNbcB?#nPB2>7MW#j$!sX|-5QKs!|#p} z?*7{`{^Q2+ia~Q=ml*+nLXcF91$`_vOrDiQy|RMTN9fZ4)I(VI(mWRWkL)L)tr^h8 zYGK3CZuDsz`mfm%=9MR*F;LHz@8YhcLut=4h4*tME!OvFUI69tB`6sA1dGfPH04Np z*OrwrvJ)BoM;^|mNrMVw!rpM8UWx3taq+qnZ8`>5wRE3Cc_owPXi0b#v^p^Sd4x3Esb`VQ+ttS7M! z#rhTNUWs)rbK6Gv-G<-o_%+6lV-`*EyL{Y&YrV2X$LHz?t;sHy^;N#(QK+X5K+U}3 z2l~yh_EG{@TVo7 zv6f~7gwL%v%l;SoJ`EbSci7#is<4$&6KxdkTDQpDx5T}R{3gC`weA*VMO;^BLm+b9eXeJr%cyklp zYe}44{x<$IZ-TXM*2q~~XHC90(sn+$`2qBNQW1xHF>baW<6#F8e#R#EiNPLW&_Fm1 zEwFR4mf{7(=q0lNck-z}kv1mNTNmgJv7dqFVW{6{^yzRLzRw|uH}b2nt{L0He5xMs z=Zv(xdDa^~elPtObalA&2-5Vj)PZS(X)vQ@%Za>;WnDA_OfBHf0fg>5)YVJbD)_3J zSk~j|Ur#W$VHm3;(RS&N5v`;g*lz~s9q?6jGHwORuJ|^(dKO<2SLo;3mDBM(MZ3bzf+pTvjP$-N z>FG6mT?_Di9m6g>CuKjGvxtKqp^NSdcf@aq<9;0T zYk|=|j^7Qi1MPae8J#cQ?en$9hP`%-$)}-HbE9P)pK*kmy=8knkHpD;CJnIHknTMT zP3D^{`%HQE5_C6ju@B=tam=M6zBTUsz5SBR!YoF}`Hk{zx^I+yoV-58R7L!-hnH^5#8b9K*9!`c|L_H| z)xnh16zTpTQu#Tw21{dg(;E@P?AfAggYhN&F6}OUFD!BXotXL=`Ok0AnAuxR*QZ1Ks)6mk-@S=e(#yts`XaCR5i>a0t4DhSk#GEB*!Rt| z7fcPL&=US#a!;wIpbTFY!*zSgGKWVrjB8&nzq{gANI}zUW?-1`}6GXp&fef(xsz_R6&%gs3;1G1yN8G zK{)~{U;$Av8hbQEvA0-bEU`w9iJDlG7+YeDsEIwsSfYtBd4J#k%skIXFfljxzW3hu zLr@k zTO7ypy#eBQ8>1@g!zj7l%_+q%WzBH)#ck&)HMlFior8T%;1L|qU3dit91ormxv=NM z@DGme;=Da9Kjer!kt^~=&d3{FnZ48f?&<#u)xd(~{TjSy!z@|GIG`q;o_LDlY0BIZ zHVH=iZk98?cGg;N9jQI%cQ0X&r7jPa{|h!E!t+H9n9qVfUaN7G?nCUQh>>41DzWC# zo(Gh$jqahdudI~AOrH3k!+ma+C(Dn;$LWiahcw^GOFsSdE#p!0Me0^+u0cy#x|N=m zRK#3Xhkud#F%#!^`iK90kptfRFLFEVzl?w$s?ULDeWFFDnaqW()l&UwxFoCHO3WM( z^9bGh#4%q6P5Gu)bnGe)!@Lf^PgM`yMwV0TKyZ_8O1YP4{PfZp;-);$_b(r@c{So+ zAP={3>SNg5xjRQ=;%&29(qoR4wUU`I?wlhZ)tyV&?YT2ozI@C{ap!c$*WR!kbLU1a zv78b5OUDxSYS0>akvyQlQiZXgV_pC6lv&`g*UF>P%Pq_$vyacl`-t%6_e?VP zUv=OclONj7|M9Dde>UxmuWS5G6oB3WcS7n#?nUxN_C@+dPeW7V+aO56^dV~Jt7(;Z z!^Pe;J@l@fZT5uLy-xn9f8D`z)sjPMVlye0({cWm&|DqbWUgK zN=Zn+wbI9?k-3YsHclEulK$bs^8}CS2NV2!!;j656@FWSUugJ>Y=!Wv z68uubm+PCck{1*FD#MrQYqHX-6Z|^EkI{E#Wv@)|n+-o&U!aw4nc(=h`EF+aQszr`FXR?ahBjO8a_XpFZ@$E3&eK+ zwc&^Ai@o~RM1sF!_#yh1uf|b=zh?NnY@YC!6I@+V?>#s>Sore^{-)sv>8rrf$mM*% zcpt9u@~+`?v$?{bRQx#J-xFTA3Lf+Mq2Y6~If{R4lK!6zUnbvptzby-zZ&lMf4wBZ z3&krOUiGq3C3t`6C8hu!m*-2l6is;H$3bMo8Y4jXD&nj zKMB6Q;fItC(X~s0PcnR7X`Zg1%IPGwi>BlBUhntva)N7`N;uzQQ-4Ts{16Js{{wXW zNrK~7P{_j7U)TE+e5T=8FXX41;P}}TX4%j@O@iacQ%FzN0vz{!f$R-=H1~v(bFf ze}j52%#QO#|Bd;EBhN|#PSU4c3$p=z(SKus;eP+x)PIBiQE2`QdXV~W(4Pve@PA%- z>c4S>;eMZ5>|e25^vgmkKc7|n^&)B!rym#6n{O0;c2Yk_8s5*Wt*0dTV#B>Z*op*S zVt5;~@9>SyOfztqRw`t&)a-Dktb>|&Jkx0(Bl$>-Yoz^;HiA8Tm)c12uGM*)&PQ~f z+swxW2jltKBG&&(+|Bi_pC!-F)BD@kmA{Ixn5RD~OuR1Y*h6#@9;fS0I(HAh=jw`o z!W=z&@#Eq{`hEOk;$OO6q?0^7q3b0N$=5Hr_kqI9xqcvxGsamdM)7{FETGd$hLgr_ z3dgiBQyAh#qcG=B7(Fj%Zp!uSEC z*FQhW9HNi=(jPUSrGDF24vC|5@_fYDEA9HvzKCrs-o~(vJ-Z>sbMumSa{t-neH-52 z@HhG1FwG6q_$qNWd?x*Uvg-8i`~JR8V;!dTNoQ!^{Vfa-&J^>(zsq{+Wy4( zo7(=T!e7;S;(E<}L!Ww5^-EjQ$2S({nYD^P?-5zWH9nqv z)VJrxuo&k`#iw1<^Q-!e^pvgjSP9g8ADHK-cb4uO=Dc2XKNgDFnp( zGugA+kLs7%i`q}=CGAqSUf)M~RXZ#FMthIEp)uNhGyj-E3thOnp77O${ z*Y8p>Osn#js;;PoA7@L|lGM#7S;Ks(YJ@md*$Ay$ou!EoWUnP!yMKIfVzH)}CA%2+ zA1a-nU7pXgMU}@w*G@$tYi(blkwDd;llTuynz|}oNlH}=qBtM>Vk56fvd~}YaN8P{dE-&3* zo`ZM#YQ`-#2d@t7;{FfcEPb=IR>!w=T&UwB9qV*ltm6_LeA5JpiTw0+N2uKhJ)RwL zf?u0|n7&O^lb@G=Lwk8$ko$eQS{H4!qr)D>jN%B5ZCZ3cc|cJg$Efaj{;2#IspRz( z+OU?k`;PB7^8L;C$k9cKe|XkcCMiPC73?zCU7p9i#K0CnW4%;Q#5Pkn*bJf}MQD)i<(?Uwj{nd)fk3+4)ltw0WehLr?Lv>2}4xFaN%t z85(HQyZL6*-qxQNBQUZ-|~7z{i3>PXglID&Y*dnRLU+YWp|ZwNwL&+#XDZT^F;N} zHQGysUGb=&D^x?b7Pl2o7OxcSj!x;{%r{dFQ=4ryUN;NW^Uz|mKyNG5=1tW!Pt3{Q z+{K6fl)V{x^C|Lh_(Pyy?__^?#HUE!{~(i)Jyra&-1A42uI%GSe|z&eYpw60eOupp z8(&n$Pr8>V-`5~R5+1F)cRfB0Acb5M#XMdO%v_A}1UhZF0 zU_T+Wv~;}QNIM;@FIaD<`Ih5DuNs*j|B&CC;??}Kym8S)-@R*A^e*}oeT#lYf9*vx zQ2TpMD|Rnt7R>LEqsjJrk7BxNY0qLW?gUDu)eHHId{W>9_hwOlea@|Sr-`~=E1nVO zeg5puF5OhxRkVygOFz7&V4pT}Nogr*^f&y>U0k}SG(!ESiSGItUhj$aUg`Ix_e+hl zCRx+$Xlv~ep=5*d5o%4+rcZ2EM32Oxlm)&wwa8SHwD)VJ$r-jd>S})WP8fZ?B{jSg zVvG{M`bgZYgJLYnm*z)l|J7siW#U`k(wFTn%Gc%Jltmb8F&1X5(wA9#`TZ9u%SWP_ zr2l00(Q){&sC`W0NmKiJenx&~epY^VevbA`TU$>1x%?GLikI2_4_XB^II1~O->o19a)iICX4gLR=Oti^18(}>L1h#a|L%5XWilRwJtkL z?FR1YAf93TDrtX+`%7zk`*Hng&fb%oiGr+ED%2e_3kRrdEfl^wdqDK`C5_S#G(zEk z$X6GtKCUQy3p3^p2raZ#en4m;Mr+Sv$G{~%$aV~Q{WRZ3+=p5lRjLv_qp#P=|CB#k z{9ND7e7z`Dy?2Cf!BK94t%@bb?`!|VZy4z>tN0|0qA^+Y zO!|XctDSLbSNYlNTSa{?(AO}r^wXZS^8LXWe?+r}rA|*AxAa_;NaX@SLVSc-h(N%+gt@`E)T+)KD&_l&2a4L_!Qvt9kMpE<^L$P;{FUOjMISZ7B;AJ-Mp^s6mjlA# z`n2(V=c(+e%vq1PPE@m*@_CcKCip$=GJC)FaqFRdbcg7xn6GKqoy|~aD*1CVo zoyL2GHeZyCin)3(c{n4RoBt-f^_gt0dIxWH1>QB}>uv4BbamOc=2q<$_dSzVne`y% zl8pHAa1&r6N64*EVJtK3QdQ+Jkj4#I{{8gs;T z*@;W)p3&LJRb~Y0S|k6Q#leTSqqK|8Szl=w{j*byf6kchM|zg$c^&bbPc$0YSN2ic zSN7+&uk0^1HeZtt^LoKN7$rErh+aLva~G)ptrY#}&>`?W8!1TxuZW3~T{*n`iUhm6yqRij zAD<=iXFN)~_bmI8F~^SBafhutOLvv-7ALy5bYE%h7qr)Fjq-Up@-g+CCxR@AzPh1a z>NV4kvnVr-kOYJ-dYByxBnd6lakw2vSif5&xrpOP>w$|UA)RN(H%!+!-}H?O%G}~c zQLg(WU;jY+vOOfJiQR+W6-D;+=rd7fq$ej{f;Q=;D7b#}u(xpQGCzTOM;Ty*WPm+% zES6k_WJRw#Mtcsg&~dB|bY1!gQq~1!Ubs$_6JB_^sOOc&)2}IW0(ik~#oapY7bSaA zRO}TUZ|nG@jt9h3psx>SA1SvjifzyEzh}95TAi`XJy50sP4ZJU(&+maX@u{Q&&>DF z>xEJFYF_VI-vN&4V?N>5cNXWY_RlTLn*|!Pd+}#I zK?-Qk%O!i!w>!E&OU5I#K4*P3Bkp_JckTZ2Dwn@$=gs>{<7WC;mlxwg$_w)!Y6SD- z;$oaecwL1m@+lJPjjj2vJJPtPLtm7}*A@MHdY<@^>Zgr(sITE0MZ+XkeL+r%Qp$~i zCS97%%x?^`%`olb8duRYEwPG*x_qqkbM2z~VQIVK4skkic}Lz^bc4_!cZs;M$hw2y zW1o3THkS`&Z^6!jjRgzKt&-ZKEKo;%t98+Nk$--S>-?P0x$j5Itmm9sFb_!jN0snw zAarNJ8l6KGO4nF?V(V5umseCKdQew%prO{;%+g3@tTI|}7bj;=yziCn)Nz-MTShKp zm(hD)>2TSjQr`HlYk6Iz-Cwc1|2WiC2TjlBVaiwwjY5Ba+E0*MMg!;ZWpBE&ekFqzUJ3z4yu<^Il#@xI>@!was zZYnz6KVyE3{<*hi#h4Q&JWuiuP6*WIh57p@`_Mi4`|1f`*Jtks-t=s?NGXDSTwxyaGDhz}!0cMD^CdU1Lm{Qk*3 zbJ%kwo71=dV-$UYC^@#E6^SnUMXHQ6|F+TPcTJA?%qVg$YFup^*v4ov<*m?Ts4+Ii zl>V*}<@FLPnuym$)&*?@`4##Ab@Q^gr@PM?y*+(~uaotXYfe`m8K9boTy#WfRIuJf z4!XN$nGey-G&|%iFwemadFch&+H7P#D#r#l-t_or4|qUasXFwyTe8#DU|n>duA6Q|>A5 z5nthWK*vLNAT4tsF>@d_bNtr0&hNCdDxBw&0zVGkyde90f1ih^vd=@FpUXZEy_k{D zDl4evOYZBk8eS)QgKrDZ9-TdMte0|!{hg#i?TpA{{fx^es!Y_v{#svEBiZYbJN;YV z%m%5bEtDL-{{yw=#>+Ld2>zhnrkb`2?Ly1YHh%xY1=d1`+wO&UH>A54;!VL$A9!Ib z(-Ez*8@Jl0)bfIiGOU%=zGAcg@35<3S;M*y->F#mqkWA!rk3f4^u*EmI345lt&WNY zzdVf5FVnqm)OR)RH7gW$C@fmo!D{p8Ob>V^e^m!osW+sd`%#Uoh35B}4lij*Y&Fdt z-Q8>N*sU7tXkr!@q_1YC8TB^X3)UCxFIZrZzp%n!hZ!Udf0&LD((Xq|yPsy37;G~$ zjU#+Vy#*-(8c@-$uiA+-Ct;!*Lswn8_YDTvzJd;0ndHZ^2`E0eLkgK|r1*v{k1wDoR>FoIvo z9u4-cfkj-SRo}k!#7q~nT+DDWyLIW8Xt}Ir+E?ih`xkX}5j;ue=;~TH_$IW@-|(6pc}ewL34^~rq1y$aV;jK@sFc_KraLoT~FwEE@Q-uWm= z=%m7YGpnc6xYAA5$x3jNCI zv!x`!LZgAVtSpM4JIyLBtnocMa<+wM`S|C!iKX9#k~S+AhMv*0zzdQzv;s&vcRPjV zW}nJF;4Qsf%(C2F_E{v#%S?v6Q9Y2-aNJ_YQOkTjR%fi(BDKaPyeyuIMv}cy;}^QJ;oR~+ zli%B~@$LCQexZ6heDdOqxt+c9+4+Tmy8I@)FmOriNcD^MkNRi!DB6c!c~TKqj(zMd zlpY>ej%6i0HmT`W^3$Aiynn7v@tV>DZ7N&SYic3tdPRXZE+OqeejqEy{yU|Rs{G&8 z`dRxyX&x%@8YZ-$gugnWnrylTK|O_{Z4e#pezoMYfxE$rp4C{PMJjUt^e|qqK}?rM z#a+Hr(KzcU>up@o^}Ma<;yu-+>3TO@Z=w8}kCt!t7`>N%BI*&4<4Wx{`@Eej6U>C% zn%^e<+8=jlZkOY(yg@OhXKcIsLoZz|-Fr+J*=M@#OJl;AyE_{b`p3*-OvvLqrO!&$ zSv!4A1CL@_elzLytSEyPG-I}{YE6G%BYvHBr~DLsAMF?Ulw!>k-&Z=iQdQj2p|>H(kw27Us9G>pvyC;-@;WgnAo3n(^5x1@&@-#@hC>95+=? z$;)p`!?UT`*)RFKQD(%yxS8&*mj&O?+?*fy>D98hGiP&auovTjOU?Ilf0A`>ghE)& zo-uzWEX3G|-<0pt+wxv|M-rI#U&4cFp!qG~xrAM9OS2gu3!qzgt8EKW>Xyx^$Wcfs~Mi*q}55XC95i^qlMY+ zYCZa}*LrW%-2adu(G4%%9{STyGj>HLe%%s&=cLkE@+oUP2%~YZo{AXv7oF6(DWkU> zb?WN#vO2$bx(_{^cM@UYIi%W7;T^YU7l+VO*~NkK_LZ)6a3BBFj-`Y3{2)E`&*sx*dHO4O=EOZpo^!9O57R&S%D}1l*YblyKmS(#x@1lA|I5<)($vt>XSoTbp9GrP zSi0iWPzF3C@a?B=^rb2h9G+ZRoK(E9z}M3)>NP(r_EKMMr8`JN%t$Z?#w^6*^89!7 zc8d1p7eamgJbOXb7*c&Q->-NgA^u z-!8i9?G5#-U8z^8Ro+ow^*A}dHosY4oO~f4r*B+du6|3ZmtEPg5osE zGH~d**~`+->r3BmBR_y1nz>k}8Hxr<8~y1mvs`1l#(Mp6_L6C9%wHpIf1bzD(;(FI z8F_=i{hrSngtzv|8>p=0+j|Y37HS;(;%TaJ^3%Iu%?hCJDtQ4fS zmC!gjW3hOcL~=Vrz_T(IT|Lt=V}RbM%%!WuMzT=6RtVs)`oR`8&+! zFn@EN+J!uAm9+>pczW>{^=;Y*%PLg$2l=s~7B0$<4JqZtUxJSF>(YdkK8>}-gfLpS zDNP7teXwQ(COqu#H!LQETG_0ap!f2QcV+2qC@XL8j6F}7z1U1^xUY0Ome!OSXNH^&W(fj1kpoh)TjyX%U z-@sd8>|U208s7M$?5!}0elFYE~YhYE_N&DfMi+(d0-htoNB+^*PB7*i_#Lwp6UBE?7^ooT6zk;-aS-K2Z2Sb(H;R zGij>b^}!}j-HYm884v7vv*7b|6HI?3iC&$l_03pFEriR6|mBo$sGJr^nJ zNXeY^_Zx~2M12^oP@f}%EVYy9&5<|DyI=SO^-?V4|C$CE>p9x0eI4IX#Qj`uSHHjC z_H$um{7N2l7fZ^#r?gLfKPs=VT(To4d7E7G1JdoW7mwfg-9b-s@^YH<@o?s9##ijQ(Pcfn^dP{)3XyqT?oTb|0dc91^TPJ z-(7aXG@qZV-3hCG=;-`}lYQvc`~*=Mo}(pB2>E?AJ3;xS44W6bHTU=NLXG=dKI?W1 zDJ{x(Q)?1)tlKS6=Zn-EMmF`dZglA-NeQ3ICe+fbnBE6(kAl^mJT>2TwrrwMWt{_l z9+0n>AKRp(|w$Wq}#kJ4nv${3--Yz z)Ts2a?$=eQyY#2XuOG}mmNWz4MR7@rdEyXUTe>ihhC4Ek0FGr%mwSW=%8btP-o^K@ZK=WDjbD)5cfGIyF6i zP<@L#-SVFKgCWHo@_lpmIpEo2v+FhDky9pqfm=oG<)Y$x<%ksUcE4WzgtTw8`M%p` z_+Q@p^|k|iyoY5=xJ{B0sTcWep>KE1Zwr09f5Bb~++C5aQ!gjI<@rjDmvtd-`+QxX zzvJ?ClCF6B&}>Y0P~b2>)O`6tp+BzA;_iYkm-i3+++8A%mRxAZ&*mZ&Q7iw)7d+BYX@Tukxi$^Rz zv3SMe7mH^szOm$&@sEe>xmv?>p5`+AH|)O3+MUbg$-G;>n{1eS=lkf`SI2A}2k59D z@9lzJ-s&hcQ2W0=qHox(DNW7eK5uJE%|kiQ%s&hDbX@7Q{IkFdCunx| zp+LzR6c35QlI9boheVS|(|aL!--Da>@^_2;rqE|6Xhp>L)E9VWSawLL`*CUsPpPA~ zT+KAED_tQPb*<)`Ua@gmNY=lvs0r=#N)~tZ`l}@A@7S(h)cVQNtoAQZfq{SU~~;U#ulA+)aO9^UiItf59oU18gnuFEFn9VLsc z6c=c?#;3-d`NKJTbM31*|2g!uspuq>5?|?S zgue9EJjCvo-}`jgyziDx{cU|G8hd)fAeC${?Wa{}t%0)4wNkrNXWk#5-LjxEUuL=Z zt1RBsDg2H-UI?!eHT&t_J{2z^{WPS%qxvd4xDe}j`D6Vw@U?g4uk!oiZrKpHbCG!5 ziQRo0&dpAgDpv>{8T?;Ql$J#-d{a-0c++y}_ZNujBJVel$J^18%X@|Kc23^wVK0%qsotJT!yR7q(pW(vezWvx zsb1DP>ygF1cmF7f;f7L^K#A69?MstDt>4RU51Xw6n$ScgqR#N{ zX!5MDhj~R4)fZ^}{Pd!2J?s?BCZ^tEe{ZY7wv^gw@C&$4UL&99=pJoD$>-f(r~3D+%a8~Wfl`AfYL=*{3_tKt>KBxj?taoJ;{{2dkk*YpqM zV6SsLrq(8{E3*Ug#{!*~1wDUElnk7&wDL7D`q4Y?e2uD~2i}WMWZXAbUtd>kQO94l zV&UY#<*v+sl%E{>U$dNjZfVa8wG-hb?!El3;_%hJK9=U}B}L7!f7Dm~duX(`C9oe8 z=}M;57mc+aO@d={a&Ej1?bw{)({`%HZkytCncKaTbZ-qr9vu8*#b61<1uyVM`4!~Oni zzf}Gkdwd#ru62yyC(QHhPSoZtc6M^ytkJ2 z%iUld^4F;3r*^F2{<}37CHVG+`|rLkOz?4rH!~S3lf0EFrmU9-Mm*wgaich^(%Vrd z@nX1*HXMp!;>Ivn?!9`0$Jo1L_TxTGyze~k!zCp174_%&;e!cY-|+VKJ@UH~yn*4K@7TwiHYa>AL?rB!&czENnO6Kc$-#ylf23)iJg zPpjR{pI6e=%}sy*Pt<_6$S#k6Kc0_wD^;?$x2xcOT>0+@KbPRmtp;keCRSF)1o!g% z-e%1>H^IF;@4u&ba)Nt#eml3F(m680yIcA}Ur2D|cy{7Mjvklb{SDt*U;PkAP4Gd6 z`|mYYC%Bi}x01)Z`~b#Q%FFXe7~Fp;!M)tRrFN9j*NYMyd0SGb4(IMlaO7${>d_mn zPH@U;GMN6KpWx_M_(Ap4|1}9d*>JDdEUDl%I~eZui~bdS(GL_nBkre4GRT#A(P;T8}9X^Q3)=QTYsL9?p}FsZH?hgOd_6`;EW%rIDD#Ef-f=LQ)T$m#&oEg z#f#9P?$s4N>LFdxSJvzLzRoIbn%P)q7o7ujlFlKzrub_8MhCiGS9B-&PZoa|)j&b-s=5fjDKdRt_pV51Mqw@ou z4UX{Xp%12dU#btL;iwPB{Knt$onNLO^4{s1=>>`deI&HCX?(;-Kz?wkvCCnfCVj^+{fW=%c5io>uMdPu>|dwd0NckwTxcem25n zD=ekW^!^sIE3_)t7P3x1DQ<7A8(c2Wn&Ta#npC^E*&&C+ zUDVoE8cpZ!7RC(-4R(Jj*8+MA%c$iochFv*YwMueysN#a2$Ti1vx9dL+RF8q>sxw&gZ_fGc5ntlT}>ZHcBJez zrjx_jTPd|Z%I8Xx`M$g!X`L^xN!DNIH)*zXkm1c&}PO#32o{4 zz8s-GWqo~6SxaB;porXUy-rE=~h9kR8K ztKeP_KThAOlaEM(R});q zhR@eNpBj@1&b*Rl$#sZ_CU_6S57tg@S_7ZpUSII@7uzRze~Ulbjn;Lu1RrGhP|fFQ zKNC@hXdm(Vg4YY`Ch>`fC6MPnN#c8b!Ov5?nc&#%p@LGg-7gXx`#d&I@_Rr9uOWZ% zT=cEog$KEGrq?f;%0enzqS~>suClXC1J6ZA!3PSb-erkjwXNZeE#8g^J~qMUCir%S zdwF#Wl{dV%cAVkEY^SzID*36MV7S*uu1@fYhI@JVtOTEAxYtvTO>p#@T>OfDad?7H zG2H75BNJRqLhE6CZqjAGS{m*C&@Z!aTqDOEA)4{@^^_ze?wZzj-Hlj525{Yl8nk&pf4* zFmf*U(<`#)Z*)J-MR5OP{YLg|TO&DM=ao8tsM*Pfbp`)TxFVBEeQI<1VR z5jxJ%I|+3*x<%+H*GfH~&`D*PwZ6XYhs?_OXWn9{eXH%M>%7!WY58_rlw_N`Ux&Ge zmey-YtEHP4>a$0A7UDR^7~pOPqZWkvI_L?ZK}LxP4K*4@XuLaGcVi9n&XpJY8tG*+ zaXm```ZHKh9jD_Y$9U!0VGc@5=&-V+dxB9Nu--;*3C(xk3i0NfjgfYsgeR4)jIA8B zlenYZ6qSIMY@+m$MTt#&9Oi~x8(Zy}5T~nJ5H7%zOC9`%&`D(}mFMQ0lnO41@-^Sv zm@#7hh}mR6YvjvEeBaX!v-)3V<&E=3$2%wzDRnhoMF{@1>2KpTP=8{DztPXpWZ**| zO{n1XFZv^V?xh5;Hr(6W9!YTc5L)06{l6u_;a}0N_N@f>{NLNv4yxcatu4Nv|DP^g zB+BLynD1uH^wt0F%75g0;JIedz=sHj@6{9EYiqdYtGgz6y9A$~;K&_$;Lj5)`B{X{ zlxx(B)6YIsNUD(RWvJq`E#twn;v_j74uyeCU=DP`h+{-&l5*#~dm3#sR>N+;T=}%QgkEL5DIC4#uXk<%WJ102uOO;xW_G_5n$S+kv z4*E-_ytQKu_x8WH6MQ?vy?pe`1mE6pFW20f;NuMU^Ff(vBU8yU)mAD`Y$!hrJhJ3Q z=!9p(Z#Nc(Ur$t=X*v&;6@lM8H%lix`$%0Q&ju%*c%N%LS0`bxfApKQ<8xmY_d3Pl zU7YtQj6CpSxaN!HSFW>-&Tcvf=p3eVd!5J%EkszOA4C5#$M0?Z7Mk1CJ*Jw4M>G&u zqV_$%kiS9*H&u^jR1mwlaqhYb(R=7w*l&h9TAAmXX-v=)2shWbq1W-;Ku5nMG{`6x zp`m47vW@W%tg7CohLxzJMlTj3pZ>_QC1aF(IJ~RA?lOu=tA&H^5bEooOz^q>mP6ne{KzYsCEo|Mw$SBo*p}WG%eD5 zdUTvue^v1#jzo$q%oRFzxM%}31o{9ki}XSCU8#|J>vC^t?MR8d-i!PTCRfU}gW>ujgs!h8_^yWU?567aRD%2Y_9^mn zl(%?-?`!dQG=J^yCirZ_cW}JtvIL)NIG&8ootEH-7(U7N$6ub{3k;vARe#!vC&3pP zK0zyaHOH0Uiw*a7)}0dkD8t7&>S=g_FE@NUx4o|26P)&wlr^|z4! z+OrMc$G-TJ{mIWXs$8|_8osyYBQ;;0#Q%ojduqQ}`3qF)q4om9z5o8t5`3-UBW#bJ zwF&+$!@a)0D#0%_-22xoOz?{g_jdFx6MUWFUY^KQ-`tM>3_LX0N&Y0$Mg-P?v@BuUB+o8O?s5sI7O#DU?>=)lDJL(P2eW>5hDNY)W zaVRr!M3@x;#_KZy2AeSWyl$$N>j;cwnany0JI;(LiRQO|GqJ3dP~`>H(H zzroO#Nh5~2l2^Wg*fIAwzZdBpb&}tdJI3Yt?(4nmiTt_0-VcT!K39A)c<&*t6kyw#rp);UE9V3U( z2nTH@w1ZJgLgO8Dme54wkc4h<hYNEt?+2k^=;jD%IkRL za)N4RqBzndaVt0(Ty96bV~R@87u0rFdK?FfuP@i`m8ZI|sU^;Jm%7XBt&bT+;Le1mxm!YB9w}?LPZ*Ep?rvrQC$ztt_C}>Pq6Y|d4t*uY-VOrqUrAevo zau2#AL--zjQ{kN_yj5VHd=YMP)k%u|-u0>6?Dh%q?^J6X7Q%PCAGj4Ee6PODfTbOt zN4-!7dl(nw-J{Lsfv!DT^*32{w2Rg4&F)U+<{n96waOD;cX*=g{qe>6CQWLZI*v8G zN4b7kr+le;D7kygEe!q?73<044*E_`1{;SVw5Q`+Dul+nqtwQPy1N;nclJ`vA&Y?? zY|eLrm5nv|ZUB zgc9E1;8Eb(=~%T(=u+1=CL?iok~>eUQtBvlsQjXib*H)W+~p?ma`#TR zF5I1OyX2nkzTvJA{=ehz&yp)B8S)RMfmR@=ow`#+{sAvEHo?Co9Qj8*eHDGZaAS37 zSAYbEN<{o830@fP{d`|faQbv1YO}qrhY9C5cJF$Id--km1jl||$nu6gyLW;&HJrId zeLr303hC4^E(+PbNw2x$hw|1^jzYGuCc3^_sfSwhmqPRBSPp-Z;B5@|_V61LocV=9 zw2^XWcF6uEBvTG{J*vW!;9CdiH`l{-T@k{k>l){L316u5I-R%ags(lWE4=HYaBY8d z#m*x3R<^U$Gg?aN@D-qbhNVOR^&&g76)G77NydLi&m&2^BNVOg@^jyrv z_GP|Qh~`E6Pd)P)i%)Oob_s84S+Oi+Z$fTo@b09YsWR72WZUj`!HQ?9B%NNako5RUk`CM#2AactK~zX`_ayMlHNI6 zoe^5oLM6s7-=RDr8;$5$z@l#IUG*y@TkUWzskI>>g(XKq|>S{h9j=F|6 z>PVd@hN)=@^CT_CbH3FT*!1_ms0J>XS{ZM&B0k5Aqf-)`mX729m;{Fg$MHWW!Qu1F zxiNmHCOG{q&LfOXaK<~cPtb=U3GV5RpO5H~;P7$ZpT(aNyuRVyPtGN{=K_9y_`_W) z<@NN-)0bBhyrHGz<$`Au9C?6o+F1X8kl_4=Z*u?U1V^r5yprBU3GPQqn4eE@