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/README.md b/README.md index cd9a80c..e24a399 100644 --- a/README.md +++ b/README.md @@ -1,218 +1,232 @@ -# ffpython - -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, 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!! - -## 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"); -``` -## 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++ - -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; -} - -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++ -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); -} -``` -## 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 ext1 - ext1.print_val(123, 45.6 , "----789---", [3.14]) - ret = ext1.return_stl() - print('test_reg_function', ret) - -def test_register_base_class(): - import ext2 - foo = ext2.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 ext2 - dumy = ext2.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(foo): - import ext2 - 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] }) - print('test_cpp_obj_to_py test_register_base_class', foo) - -def test_cpp_obj_py_obj(dumy): - import ext2 - 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) - print('test_cpp_obj_py_obj', dumy) - - return dumy - -``` - -## 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. + + diff --git a/example.cpp b/example.cpp index f1d63f9..bf6ce6d 100644 --- a/example.cpp +++ b/example.cpp @@ -5,176 +5,181 @@ #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); +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("time.asctime=%s\n", ffpython.call("time", "asctime").c_str()); - int a1 = 100; float a2 = 3.14f; string a3 = "OhWell"; - ffpython.call("fftest", "test_base", a1, a2, a3); + 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", "testBase", a1, a2, a3); } -void test_stl(ffpython_t& ffpython) +void testStl(FFPython& 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); + ffpython.call("fftest", "testStl", a1, a2, a3); } -void test_return_stl(ffpython_t& ffpython) +void test_returnStl(FFPython& ffpython) { - typedef 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, int a2, const string& a3, const vector& a4) +static int printVal(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 +struct OpsTest { - static list return_stl() + static std::list returnStl() { - list ret;ret.push_back(1024); + std::list ret;ret.push_back(1024); printf("%s\n", __FUNCTION__); return ret; } }; - -void test_reg_function() +void testRegisterBaseClass(FFPython& 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", "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() - { - printf("%s\n", __FUNCTION__); - } - int get_value() const { return m_value; } - void set_value(int v_) { m_value = v_; } - void test_stl(map >& v_) + virtual ~Foo() { printf("%s\n", __FUNCTION__); } - int m_value; + int getValue() { return nValue; } + void setValue(int v_) { nValue = v_; } + void testStl(std::map >& v_) + { + printf("%s\n", __FUNCTION__); + } + int nValue; }; -class dumy_t: public foo_t +class Dumy : public Foo { 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(int v_) :Foo(v_) + { + printf("%s\n", __FUNCTION__); + } + ~Dumy() + { + printf("%s\n", __FUNCTION__); + } + void dump() + { + printf("%s\n", __FUNCTION__); + } }; -static foo_t* obj_test(dumy_t* p) +static Foo* objTest(Dumy* p) { - printf("%s\n", __FUNCTION__); - return p; + printf("%s\n", __FUNCTION__); + return p; } -void test_register_base_class(ffpython_t& ffpython) +std::string testRegFunction(FFPython& 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.regFunc(&printVal, "printVal") + .regFunc(&OpsTest::returnStl, "returnStl"); - ffpython.reg_class("dumy_t", "dumy_t class inherit foo_t ctor ", "foo_t") - .reg(&dumy_t::dump, "dump"); + ffpython.regClass("Foo") + .regMethod(&Foo::getValue, "getValue") + .regMethod(&Foo::setValue, "setValue") + .regMethod(&Foo::testStl, "testStl") + .regField(&Foo::nValue, "nValue"); - ffpython.reg(obj_test, "obj_test"); + ffpython.regClass("Dumy", "Foo") + .regMethod(&Dumy::dump, "dump"); - ffpython.init("ext2"); - ffpython.call("fftest", "test_register_base_class"); -}; + 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); - 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, 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[]) { - Py_Initialize(); + try { - ffpython_t::add_path("./"); - ffpython_t ffpython;//("ext2"); + FFPython ffpython; + testRegFunction(ffpython); + ffpython.addPath("./"); + ffpython.addPath("../"); - 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("testBase", testBase(ffpython)); + + TestGuard("testStl", testStl(ffpython)); + ffpython.call("fftest", "testRegFunction"); + + TestGuard("testRegisterBaseClass", testRegisterBaseClass(ffpython)); + + TestGuard("testRegisterInheritClass", testRegisterInheritClass(ffpython)); + + TestGuard("testCppObjToPy", testCppObjToPy(ffpython)); + + TestGuard("testPyClassLambda", testPyClassLambda(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(); + } + catch(std::exception& e) { + printf("exception<%s>\n", e.what()); + } printf("main exit...\n"); return 0; } diff --git a/ffpython.cpp b/ffpython.cpp new file mode 100644 index 0000000..fc0ead9 --- /dev/null +++ b/ffpython.cpp @@ -0,0 +1,439 @@ + +#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() +{ + 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(); +} +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; + 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; +} +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; +} +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 bfbf8d7..06cb89c 100644 --- a/ffpython.h +++ b/ffpython.h @@ -1,3925 +1,1788 @@ -#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 -{ - 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() - { - 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; - } - - 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虚拟机 - 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_) - { - 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() - { - 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 +#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; +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, + 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); + 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 = ""); + 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); + } + 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); + 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_); + 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; +}; +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 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 { +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 ScriptRefTraits::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 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)); + } +}; +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 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)); + } +}; +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 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)); + } +}; +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 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)); + } +}; +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 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)); + } +}; +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 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)); + } +}; +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 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)); + } +}; +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 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)); + } +}; +//!ֵ +//!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 ScriptRefTraits::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 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; + } +}; +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 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; + } +}; +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 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; + } +}; +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 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; + } +}; +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 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; + } +}; +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 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; + } +}; +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 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; + } +}; +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 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; + } +}; +//!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 ScriptRefTraits::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 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() { + delete (CLASS_TYPE*)(this->pobjArg); + } +}; +template +class ScriptClassImpl :public ScriptIterface +{ +public: + typedef CLASS_TYPE ClassTypeReal; + ScriptClassImpl() :ScriptIterface(3) {} + virtual void* handleNew() { + 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() { + delete (CLASS_TYPE*)(this->pobjArg); + } +}; +template +class ScriptClassImpl :public ScriptIterface +{ +public: + typedef CLASS_TYPE ClassTypeReal; + ScriptClassImpl() :ScriptIterface(4) {} + virtual void* handleNew() { + 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() { + delete (CLASS_TYPE*)(this->pobjArg); + } +}; +template + class ScriptClassImpl :public ScriptIterface +{ +public: + typedef CLASS_TYPE ClassTypeReal; + ScriptClassImpl() :ScriptIterface(5) {} + virtual void* handleNew() { + 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() { + delete (CLASS_TYPE*)(this->pobjArg); + } +}; +template + class ScriptClassImpl :public ScriptIterface +{ +public: + typedef CLASS_TYPE ClassTypeReal; + ScriptClassImpl() :ScriptIterface(6) {} + virtual void* handleNew() { + 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() { + delete (CLASS_TYPE*)(this->pobjArg); + } +}; +template + class ScriptClassImpl :public ScriptIterface +{ +public: + typedef CLASS_TYPE ClassTypeReal; + ScriptClassImpl() :ScriptIterface(7) {} + virtual void* handleNew() { + 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() { + delete (CLASS_TYPE*)(this->pobjArg); + } +}; +template + class ScriptClassImpl :public ScriptIterface +{ +public: + typedef CLASS_TYPE ClassTypeReal; + ScriptClassImpl() :ScriptIterface(8) {} + virtual void* handleNew() { + 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() { + delete (CLASS_TYPE*)(this->pobjArg); + } +}; +template + class ScriptClassImpl :public ScriptIterface +{ +public: + typedef CLASS_TYPE ClassTypeReal; + ScriptClassImpl() :ScriptIterface(9) {} + virtual void* handleNew() { + 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() { + 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 ScriptRefTraits::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 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)); + } +}; +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 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)); + } +}; +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 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)); + } +}; +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 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)); + } +}; +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 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)); + } +}; +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 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)); + } +}; +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 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)); + } +}; +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 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)); + } +}; +//!ֵ෽ +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 ScriptRefTraits::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 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; + } +}; +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 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; + } +}; +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 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; + } +}; +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 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; + } +}; +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 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; + } +}; +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 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; + } +}; +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 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; + } +}; +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 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; + } +}; +//!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 94e7efe..890f80f 100644 --- a/fftest.py +++ b/fftest.py @@ -1,78 +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 ext1 - ext1.print_val(123, 45.6 , "----789---", [3.14]) - ret = ext1.return_stl() - print('test_reg_function', ret) - -def test_register_base_class(): - import ext2 - foo = ext2.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 ext2 - dumy = ext2.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 ext2 - 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 - 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) - 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 + diff --git a/VersionForRead/ffpython.cpp b/oldversion/python2.7/VersionForRead/ffpython.cpp similarity index 97% rename from VersionForRead/ffpython.cpp rename to oldversion/python2.7/VersionForRead/ffpython.cpp index c78bf09..fee25ca 100644 --- a/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/VersionForRead/ffpython.h b/oldversion/python2.7/VersionForRead/ffpython.h similarity index 97% rename from VersionForRead/ffpython.h rename to oldversion/python2.7/VersionForRead/ffpython.h index 5585f5f..22faabe 100644 --- a/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/VersionForRead/pyops_base.h b/oldversion/python2.7/VersionForRead/pyops_base.h similarity index 96% rename from VersionForRead/pyops_base.h rename to oldversion/python2.7/VersionForRead/pyops_base.h index ccb0f5c..9fdb066 100644 --- a/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/VersionForRead/pyops_for_embed.h b/oldversion/python2.7/VersionForRead/pyops_for_embed.h similarity index 95% rename from VersionForRead/pyops_for_embed.h rename to oldversion/python2.7/VersionForRead/pyops_for_embed.h index e91a7f3..b3c734f 100644 --- a/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/VersionForRead/pyops_for_extend.h b/oldversion/python2.7/VersionForRead/pyops_for_extend.h similarity index 97% rename from VersionForRead/pyops_for_extend.h rename to oldversion/python2.7/VersionForRead/pyops_for_extend.h index e91ca90..aa6cc88 100644 --- a/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/oldversion/python2.7/ffpython.h b/oldversion/python2.7/ffpython.h new file mode 100644 index 0000000..1b95049 --- /dev/null +++ b/oldversion/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.ncb b/vs2008.x86/ffpython.ncb deleted file mode 100644 index 84a8fce..0000000 Binary files a/vs2008.x86/ffpython.ncb and /dev/null differ 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 b561109..0000000 Binary files a/vs2008.x86/ffpython.suo and /dev/null differ 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