diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b95a414 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/vs2008.x86/x64 +/vs2008.x86/.vs +/__pycache__ diff --git a/example.cpp b/example.cpp index bf6ce6d..3d72f37 100644 --- a/example.cpp +++ b/example.cpp @@ -5,9 +5,11 @@ #include "ffpython.h" +extern PyMethodDef EmbMethods[]; + #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 testBase(FFPython& ffpython) { @@ -17,7 +19,12 @@ void testBase(FFPython& ffpython) 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); + PyObject* ret = ffpython.call("fftest", "testBase", a1, a2, a3); + std::string str; + ScriptCppOps::scriptToCpp(ret, str); + printf("call testBase return:%s\n", str.c_str()); + + ffpython.globalGC(ret); } void testStl(FFPython& ffpython) @@ -113,6 +120,7 @@ std::string testRegFunction(FFPython& ffpython) .regMethod(&Dumy::dump, "dump"); ffpython.regFunc(objTest, "objTest"); + ffpython.runCode("ffpython.objTest(None)"); return "cppext"; } @@ -142,44 +150,62 @@ void testPyClassLambda(FFPython& ffpython) Py_XDECREF(pFunc); PyObject* pobj = ffpython.call("fftest", "testCppObjReturnPyObj"); - Py_INCREF(pobj); + Py_XINCREF(pobj); std::vector args1; args1.push_back(ScriptCppOps::scriptFromCpp(1111)); args1.push_back(ScriptCppOps::scriptFromCpp("soNice")); ffpython.callMethodByObjRet(pobj, "sayHi", args1); Py_XDECREF(pobj); + ffpython.setVar("fftest", "mensong", NULL); + PyObject* nullo = ffpython.getVar("fftest", "mensong"); + nullo = ffpython.getScriptVar("fftest", "mensong"); } int main(int argc, char* argv[]) { - try { + try + { + FFPython* ffpython = FFPython::Ins(); + + ffpython->addPath("E:\\"); + std::string ret; + std::vector args; + args.push_back(ScriptCppOps::scriptFromCpp("{\"capturePoint\":{\"X\":757.59,\"Y\":400,\"Z\":725.685,\"Rx\":-175.591,\"Ry\":-14.586,\"Rz\":95.639},\"initRobotPos\":{\"X\":120.744,\"Y\":382.915,\"Z\":300,\"Rx\":0,\"Ry\":0,\"Rz\":-22.155}}")); + bool res = ffpython->callFunc("robot", "trans", args, &ret); + std::string ret1 = ffpython->call("robot", "trans", "{\"capturePoint\":{\"X\":757.59,\"Y\":400,\"Z\":725.685,\"Rx\":-175.591,\"Ry\":-14.586,\"Rz\":95.639},\"initRobotPos\":{\"X\":120.744,\"Y\":382.915,\"Z\":300,\"Rx\":0,\"Ry\":0,\"Rz\":-22.155}}"); - FFPython ffpython; - testRegFunction(ffpython); - ffpython.addPath("./"); - ffpython.addPath("../"); + ffpython->setVar("robot", "a", "123"); + std::string astr = ffpython->getVar("robot", "a"); - TestGuard("testBase", testBase(ffpython)); + testRegFunction(*ffpython); + ffpython->addPath("./"); + ffpython->addPath("../"); + ffpython->addPath("D:\\Working\\ffpython_org"); - TestGuard("testStl", testStl(ffpython)); - ffpython.call("fftest", "testRegFunction"); + + TestGuard("testBase", testBase(*ffpython)); - TestGuard("testRegisterBaseClass", testRegisterBaseClass(ffpython)); + TestGuard("testStl", testStl(*ffpython)); + ffpython->call("fftest", "testRegFunction"); - TestGuard("testRegisterInheritClass", testRegisterInheritClass(ffpython)); - - TestGuard("testCppObjToPy", testCppObjToPy(ffpython)); + TestGuard("testRegisterBaseClass", testRegisterBaseClass(*ffpython)); - TestGuard("testPyClassLambda", testPyClassLambda(ffpython)); + TestGuard("testRegisterInheritClass", testRegisterInheritClass(*ffpython)); + + TestGuard("testCppObjToPy", testCppObjToPy(*ffpython)); -#ifdef _WIN32 - system("pause"); -#endif + TestGuard("testPyClassLambda", testPyClassLambda(*ffpython)); } catch(std::exception& e) { printf("exception<%s>\n", e.what()); } + + FFPython::FreeIns(); printf("main exit...\n"); + +#ifdef _WIN32 + system("pause"); +#endif return 0; } diff --git a/ffpython.cpp b/ffpython.cpp index fc0ead9..9e2d0d9 100644 --- a/ffpython.cpp +++ b/ffpython.cpp @@ -1,6 +1,6 @@ #include "ffpython.h" -using namespace ff; +#include std::vector FFPython::m_regFuncs; std::map FFPython::m_allocObjs; @@ -16,7 +16,7 @@ static PyObject* callExt(PyObject* self, PyObject* args) return NULL; ScriptIterface* pfunc = FFPython::getRegFuncByID(idFunc); if (!pfunc) { - Py_RETURN_NONE; + return NULL; } pfunc->clearTmpArg();//!Ö§³ÖµÝ¹é pfunc->pobjArg = (void*)addrObj;//!Èç¹ûÊÇÀà·½·¨£¬ÐèÒªÓÐÀàÖ¸Õë²ÎÊý @@ -51,7 +51,7 @@ static PyObject* callExt(PyObject* self, PyObject* args) { std::map::iterator it = FFPython::m_allocObjs.find(pfunc->pobjArg); if (it == FFPython::m_allocObjs.end()) { - Py_RETURN_NONE; + return NULL; } } ret = pfunc->handleRun(); @@ -67,6 +67,25 @@ static PyMethodDef EmbMethods[] = { {NULL, NULL, 0, NULL} }; +FFPython* FFPython::s_ins = NULL; +FFPython* FFPython::Ins() +{ + if (s_ins) + return s_ins; + + s_ins = new FFPython; + return s_ins; +} + +void FFPython::FreeIns() +{ + if (s_ins) + { + delete s_ins; + s_ins = NULL; + } +} + FFPython::FFPython() { #ifdef PYTHON_3 @@ -84,7 +103,7 @@ FFPython::FFPython() return PyModule_Create(&EmbModule); } }; - PyImport_AppendInittab("ffpython", &PyInitTmpTool::PyInit_emb); + int n = PyImport_AppendInittab("ffpython", &PyInitTmpTool::PyInit_emb); Py_Initialize(); #else Py_Initialize(); @@ -159,26 +178,28 @@ FFPython::~FFPython() delete m_regFuncs[i]; } m_regFuncs.clear(); - for (size_t i = 0; i < m_listGlobalCache.size(); ++i) + for (std::set::iterator it = m_listGlobalGC.begin(); + it != m_listGlobalGC.end(); ++it) { - Py_XDECREF(m_listGlobalCache[i]); + Py_XDECREF(*it); } - m_listGlobalCache.clear(); + m_listGlobalGC.clear(); if (Py_IsInitialized()) Py_Finalize(); } void FFPython::addPath(const std::string& path) { + //replace \\ to / + std::string _path = path; + std::replace(_path.begin(), _path.end(), '\\', '/'); + 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()); + 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) { @@ -186,7 +207,10 @@ PyObject* FFPython::callFuncByObj(PyObject* pFunc, std::vector& objAr 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]); + if (objArgs[i]) + PyTuple_SetItem(pArgs, i, objArgs[i]); + else + PyTuple_SetItem(pArgs, i, Py_None); } objArgs.clear(); pValue = PyObject_CallObject(pFunc, pArgs); @@ -198,31 +222,25 @@ PyObject* FFPython::callFuncByObj(PyObject* pFunc, std::vector& objAr } objArgs.clear(); } - if (PyErr_Occurred()) { - traceback(m_strErr); - } - if (!pValue) - Py_RETURN_FALSE; return pValue; } PyObject* FFPython::getScriptVarByObj(PyObject* pModule, const std::string& strVarName) { + if (!pModule) + return NULL; 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; + return NULL; PyObject* pModule = PyImport_Import(pName); Py_DECREF(pName); if (!pModule) { - Py_RETURN_NONE; + return NULL; } PyObject* pValue = getScriptVarByObj(pModule, strVarName); Py_DECREF(pModule); @@ -231,11 +249,10 @@ PyObject* FFPython::getScriptVar(const std::string& strMod, const std::string& s PyObject* FFPython::callFunc(const std::string& modName, const std::string& funcName, std::vector& objArgs) { PyObject* pFunc = getScriptVar(modName, funcName); + if (!pFunc) + return NULL; PyObject* pValue = callFuncByObj(pFunc, objArgs); Py_XDECREF(pFunc); - - if (!pValue) - Py_RETURN_FALSE; return pValue; } FFPython& FFPython::reg(ScriptIterface* pObj, const std::string& name, @@ -296,7 +313,7 @@ int FFPython::traceback(std::string& ret_) PyObject* err = PyErr_Occurred(); if (!err) { - return 0; + return 1; } PyObject* ptype = NULL, * pvalue = NULL, * ptraceback = NULL; @@ -305,7 +322,7 @@ int FFPython::traceback(std::string& ret_) PyErr_Fetch(&ptype, &pvalue, &ptraceback); if (pvalue) { - if (true == PyList_Check(pvalue)) + if (PyList_Check(pvalue)) { int64_t n = PyList_Size(pvalue); for (int64_t i = 0; i < n; ++i) @@ -316,13 +333,13 @@ int FFPython::traceback(std::string& ret_) Py_DECREF(pystr); } } - else if (true == PyTuple_Check(pvalue)) + else if (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)) + if (PyTuple_Check(tmp_str)) { int64_t m = PyTuple_Size(tmp_str); for (int64_t j = 0; j < m; ++j) @@ -366,7 +383,7 @@ int FFPython::traceback(std::string& ret_) 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)) + if (pyth_val && PyList_Check(pyth_val)) { int64_t n = PyList_Size(pyth_val); for (int64_t i = 0; i < n; ++i) @@ -398,6 +415,19 @@ int FFPython::traceback(std::string& ret_) printf("ffpython traceback:%s\n", ret_.c_str()); return 0; } + +void FFPython::globalGC(PyObject* o) +{ + if (!o) + return; + + std::set::iterator itFinder = m_listGlobalGC.find(o); + if (itFinder == m_listGlobalGC.end()) + { + m_listGlobalGC.insert(o); + } +} + bool FFPython::reload(const std::string& py_name_) { PyObject* pName = NULL, * pModule = NULL; @@ -407,7 +437,6 @@ bool FFPython::reload(const std::string& py_name_) Py_DECREF(pName); if (NULL == pModule) { - traceback(m_strErr); return false; } @@ -415,11 +444,10 @@ bool FFPython::reload(const std::string& py_name_) Py_DECREF(pModule); if (NULL == pNewMod) { - traceback(m_strErr); return false; } Py_DECREF(pNewMod); - return 0; + return true; } bool FFPython::load(const std::string& py_name_) { @@ -430,10 +458,9 @@ bool FFPython::load(const std::string& py_name_) Py_DECREF(pName); if (NULL == pModule) { - traceback(m_strErr); return false; } Py_DECREF(pModule); - return 0; + return true; } diff --git a/ffpython.h b/ffpython.h index 06cb89c..1741428 100644 --- a/ffpython.h +++ b/ffpython.h @@ -13,8 +13,7 @@ #include #include #include -namespace ff -{ + #ifndef PyString_Check #define PYTHON_3 #define PyString_Check PyUnicode_Check @@ -23,6 +22,7 @@ namespace ff #define PyString_FromStringAndSize PyUnicode_FromStringAndSize #define PyString_FromString PyUnicode_FromString #endif + #ifdef _WIN32 #define SAFE_SPRINTF _snprintf_s #define PTR_NUMBER int64_t @@ -30,7 +30,9 @@ namespace ff #define SAFE_SPRINTF snprintf #define PTR_NUMBER int64_t #endif + #define PYCTOR int (*) + template struct ScriptCppOps; @@ -90,7 +92,8 @@ template class ScriptFieldImpl; class ScriptRawImpl :public ScriptIterface { public: - typedef PyObject* (*FuncType)(std::vector&); FuncType func; + typedef PyObject* (*FuncType)(std::vector&); + FuncType func; ScriptRawImpl(FuncType f) :func(f) {} virtual PyObject* handleRun() { return func(tmpArgs); @@ -108,8 +111,15 @@ enum FFScriptTypeDef { class FFPython { public: + static FFPython* Ins(); + static void FreeIns(); + +private: FFPython(); ~FFPython(); + static FFPython* s_ins; + +public: void addPath(const std::string& path); void runCode(const std::string& code); bool reload(const std::string& pyMod); @@ -143,39 +153,52 @@ class FFPython template bool callFuncByObj(PyObject* pFunc, std::vector& objArgs, RET* pRet) { + if (!pFunc) + return false; + ScriptObjRefGuard retObj(CheckType::IsScriptObject(), callFuncByObj(pFunc, objArgs)); if (pRet) { - *pRet = ScriptCppOps::scriptToCpp(retObj.value, *pRet); + ScriptCppOps::scriptToCpp(retObj.value, *pRet); } - return getErrMsg().empty(); + + std::string errMsg; + return !getErr(errMsg); } template RET_V callFuncByObjRet(PyObject* pFunc, std::vector& objArgs) { RET_V ret = InitValueTrait::value(); - callFuncByObj(pFunc, objArgs, &ret); - return getErrMsg().empty(); + if (!pFunc) + return ret; + return callFuncByObj(pFunc, objArgs, &ret); } template RET_V callMethodByObjRet(PyObject* pObj, const std::string& nameFunc, std::vector& objArgs) { + if (!pObj) + return NULL; + PyObject* pFunc = PyObject_GetAttrString(pObj, nameFunc.c_str()); if (!pFunc) { - Py_RETURN_NONE; + return NULL; } RET_V ret = InitValueTrait::value(); callFuncByObj(pFunc, objArgs, &ret); Py_XDECREF(pFunc); - return getErrMsg().empty(); + + std::string errMsg; + return !getErr(errMsg); } 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); + ScriptCppOps::scriptToCpp(retObj.value, *pRet); } - return getErrMsg().empty(); + + std::string errMsg; + return !getErr(errMsg); } //! µ÷ÓÃpythonº¯Êý£¬×î¶àÖ§³Ö9¸ö²ÎÊý template @@ -348,8 +371,11 @@ class FFPython 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(); + if (!pyMod) + return ret; + ScriptObjRefGuard retObj(CheckType::IsScriptObject(), getScriptVarByObj(pyMod, strVarName)); + ScriptCppOps::scriptToCpp(retObj.value, ret); return ret; } @@ -370,7 +396,6 @@ class FFPython pModule = PyImport_Import(pName); Py_DECREF(pName); if (NULL == pModule){ - traceback(m_strErr); return false; } @@ -379,7 +404,10 @@ class FFPython Py_DECREF(pModule); return true; } - const std::string& getErrMsg() { return m_strErr; } + const bool getErr(std::string& strErr) + { + return traceback(strErr) == 0; + } std::vector& allocArgList() { m_listArgs.clear(); return m_listArgs; } static ScriptIterface* getRegFuncByID(size_t i) { if (i < m_regFuncs.size()) { @@ -389,12 +417,13 @@ class FFPython } int traceback(std::string& ret_); void cacheObj(PyObject* b) { m_listArgs.push_back(b); } + void globalGC(PyObject* o); + private: - std::string m_strErr; std::vector m_listArgs; static std::vector m_regFuncs; std::string m_curRegClassName; - std::vector m_listGlobalCache; + std::set m_listGlobalGC; public: static std::map m_allocObjs; static PyObject* pyobjBuildTmpObj; @@ -403,11 +432,12 @@ template<> struct ScriptCppOps { static PyObject* scriptFromCpp(int8_t n) { return PyLong_FromLong(long(n)); } static bool scriptToCpp(PyObject* pvalue, int8_t& ret) { + if (!pvalue) { return false; } 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; } + else { return false; } return true; } }; @@ -415,11 +445,12 @@ template<> struct ScriptCppOps { static PyObject* scriptFromCpp(uint8_t n) { return PyLong_FromLong(long(n)); } static bool scriptToCpp(PyObject* pvalue, uint8_t& ret) { + if (!pvalue) { return false; } 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; } + else { return false; } return true; } }; @@ -427,11 +458,12 @@ template<> struct ScriptCppOps { static PyObject* scriptFromCpp(int16_t n) { return PyLong_FromLong(long(n)); } static bool scriptToCpp(PyObject* pvalue, int16_t& ret) { + if (!pvalue) { return false; } 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; } + else { return false; } return true; } }; @@ -439,11 +471,12 @@ template<> struct ScriptCppOps { static PyObject* scriptFromCpp(uint16_t n) { return PyLong_FromLong(long(n)); } static bool scriptToCpp(PyObject* pvalue, uint16_t& ret) { + if (!pvalue) { return false; } 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; } + else { return false; } return true; } }; @@ -451,11 +484,12 @@ template<> struct ScriptCppOps { static PyObject* scriptFromCpp(int32_t n) { return PyLong_FromLong(long(n)); } static bool scriptToCpp(PyObject* pvalue, int32_t& ret) { + if (!pvalue) { return false; } 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; } + else { return false; } return true; } }; @@ -463,11 +497,12 @@ template<> struct ScriptCppOps { static PyObject* scriptFromCpp(uint32_t n) { return PyLong_FromLong(long(n)); } static bool scriptToCpp(PyObject* pvalue, uint32_t& ret) { + if (!pvalue) { return false; } 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; } + else { return false; } return true; } }; @@ -475,11 +510,12 @@ template<> struct ScriptCppOps { static PyObject* scriptFromCpp(int64_t n) { return PyLong_FromLongLong(n); } static bool scriptToCpp(PyObject* pvalue, int64_t& ret) { + if (!pvalue) { return false; } 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; } + else { return false; } return true; } }; @@ -487,45 +523,50 @@ template<> struct ScriptCppOps { static PyObject* scriptFromCpp(uint64_t n) { return PyLong_FromLongLong(long(n)); } static bool scriptToCpp(PyObject* pvalue, uint64_t& ret) { + if (!pvalue) { return false; } 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; } + else { 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 (!pvalue) { return false; } 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; } + else { 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 (!pvalue) { return false; } 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; } + else { 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 (!pvalue) { return false; } if (Py_False == pvalue || Py_None == pvalue) { ret = false; } - else { ret = true; } + else { return false; } 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 (!pvalue) { return false; } if (PyLong_Check(pvalue)) { char buff[64] = { 0 }; SAFE_SPRINTF(buff, sizeof(buff), "%ld", PyLong_AsLong(pvalue)); @@ -546,24 +587,28 @@ template<> struct ScriptCppOps { PyString_AsStringAndSize(pvalue, (&pstr), &size); if (pstr) ret.assign(pstr, size); + else + ret.clear(); } - else { ret.clear(); return false; } + else { 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 (!pvalue) { return false; } if (PyString_Check(pvalue)) { ret = PyString_AsString(pvalue); } - else { ret = ""; return false; } + else { return false; } return true; } }; template<> struct ScriptCppOps { static PyObject* scriptFromCpp(void* n) { return PyLong_FromVoidPtr(n); } static bool scriptToCpp(PyObject* pvalue, void*& ret) { + if (!pvalue) { return false; } ret = PyLong_AsVoidPtr(pvalue); return true; } @@ -574,6 +619,7 @@ template struct ScriptCppOps { template<> struct ScriptCppOps { static PyObject* scriptFromCpp(PyObject* n) { return n; } static bool scriptToCpp(PyObject* pvalue, PyObject*& ret) { + if (!pvalue) { return false; } ret = pvalue; return true; } @@ -584,11 +630,15 @@ template struct ScriptCppOps { if (!FFPython::pyobjBuildTmpObj) { Py_RETURN_NONE; } + if (!n) + 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)); + PyObject* arg0 = ScriptCppOps::scriptFromCpp(BindClassName); + PyTuple_SetItem(pArgs, 0, (arg0 ? arg0 : Py_None)); PyTuple_SetItem(pArgs, 1, PyLong_FromVoidPtr(n)); pValue = PyObject_CallObject(pFunc, pArgs); Py_DECREF(pArgs); @@ -600,11 +650,15 @@ template struct ScriptCppOps { return pValue; } static bool scriptToCpp(PyObject* pyobjVal, T*& ret) { + if (!pyobjVal) { return false; } PyObject* pValue = PyObject_GetAttrString(pyobjVal, "_cppInterObj_"); if (pValue) { ret = (T*)PyLong_AsVoidPtr(pValue); Py_DECREF(pValue); } + else { + return false; + } return true; } }; @@ -623,9 +677,11 @@ struct ScriptCppOps > } static bool scriptToCpp(PyObject* pyobjVal, std::vector& retVal) { - retVal.clear(); - if (true == PyTuple_Check(pyobjVal)) + if (!pyobjVal) { return false; } + + if (PyTuple_Check(pyobjVal)) { + retVal.clear(); Py_ssize_t n = PyTuple_Size(pyobjVal); for (Py_ssize_t i = 0; i < n; ++i) { @@ -633,8 +689,9 @@ struct ScriptCppOps > ScriptCppOps::scriptToCpp(PyTuple_GetItem(pyobjVal, i), retVal.back()); } } - else if (true == PyList_Check(pyobjVal)) + else if (PyList_Check(pyobjVal)) { + retVal.clear(); Py_ssize_t n = PyList_Size(pyobjVal); for (Py_ssize_t i = 0; i < n; ++i) { @@ -662,9 +719,11 @@ struct ScriptCppOps > } static bool scriptToCpp(PyObject* pyobjVal, std::list& retVal) { - retVal.clear(); - if (true == PyTuple_Check(pyobjVal)) + if (!pyobjVal) { return false; } + + if (PyTuple_Check(pyobjVal)) { + retVal.clear(); Py_ssize_t n = PyTuple_Size(pyobjVal); for (Py_ssize_t i = 0; i < n; ++i) { @@ -672,8 +731,9 @@ struct ScriptCppOps > ScriptCppOps::scriptToCpp(PyTuple_GetItem(pyobjVal, i), retVal.back()); } } - else if (true == PyList_Check(pyobjVal)) + else if (PyList_Check(pyobjVal)) { + retVal.clear(); Py_ssize_t n = PyList_Size(pyobjVal); for (Py_ssize_t i = 0; i < n; ++i) { @@ -702,13 +762,19 @@ struct ScriptCppOps > } static bool scriptToCpp(PyObject* pyobjVal, std::set& retVal) { - retVal.clear(); + if (!pyobjVal) { return false; } + PyObject* iter = PyObject_GetIter(pyobjVal); + if (!iter) { + return false; + } + + retVal.clear(); PyObject* item = NULL; while (NULL != iter && NULL != (item = PyIter_Next(iter))) { T tmp(); - if (ScriptCppOps::scriptToCpp(item, tmp)) + if (!ScriptCppOps::scriptToCpp(item, tmp)) { Py_DECREF(item); Py_DECREF(iter); @@ -742,9 +808,12 @@ struct ScriptCppOps > } static bool scriptToCpp(PyObject* pyobjVal, std::map& retVal) { - retVal.clear(); - if (true == PyDict_Check(pyobjVal)) + if (!pyobjVal) { return false; } + + if (PyDict_Check(pyobjVal)) { + retVal.clear(); + PyObject* key = NULL, * value = NULL; Py_ssize_t pos = 0; @@ -752,11 +821,16 @@ struct ScriptCppOps > { T arg1 = InitValueTrait::value(); R arg2 = InitValueTrait::value(); - ScriptCppOps::scriptToCpp(key, arg1); - ScriptCppOps::scriptToCpp(value, arg2); - retVal[arg1] = arg2; + if (ScriptCppOps::scriptToCpp(key, arg1) && + ScriptCppOps::scriptToCpp(value, arg2)) + { + retVal[arg1] = arg2; + } } } + else { + return false; + } return true; } }; @@ -1781,8 +1855,7 @@ class ScriptFieldImpl : public ScriptIterface { Py_RETURN_NONE; } }; -//!Àà×ֶνáÊø -}//end namespace ff + #endif // ! _FFPYTHON_H_ diff --git a/fftest.py b/fftest.py index 890f80f..5656a2b 100644 --- a/fftest.py +++ b/fftest.py @@ -2,7 +2,7 @@ def testBase(a1, a2, a3): print('testBase', a1, a2, a3) - return 0 + return str(a1)+str(a2)+str(a3) def testStl(a1, a2, a3): print('testStl', a1, a2, a3) @@ -72,9 +72,11 @@ 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) diff --git a/vs2008.x86/ffpython.vcxproj b/vs2008.x86/ffpython.vcxproj index 1dcff00..e155b27 100644 --- a/vs2008.x86/ffpython.vcxproj +++ b/vs2008.x86/ffpython.vcxproj @@ -22,29 +22,29 @@ {A7E1C195-DF68-4713-A758-E27C6E02858C} ffpython Win32Proj - 10.0.17763.0 + 10.0 Application - v141 + v143 Unicode true Application - v141 + v143 Unicode true Application - v141 + v143 Unicode Application - v141 + v143 Unicode @@ -109,12 +109,12 @@ Level3 ProgramDatabase - C:\Users\zhaoxinfeng.evan\AppData\Local\Programs\Python\Python37\include;%(AdditionalIncludeDirectories) + C:\Python311\include;%(AdditionalIncludeDirectories) true Console - C:\Users\zhaoxinfeng.evan\AppData\Local\Programs\Python\Python37\libs;%(AdditionalLibraryDirectories) + C:\Python311\libs;%(AdditionalLibraryDirectories) @@ -143,7 +143,7 @@ MaxSpeed true - ../;C:\Users\zhaoxinfeng.evan\AppData\Local\Programs\Python\Python37\include;%(AdditionalIncludeDirectories) + C:\Python311\include;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) MultiThreadedDLL true @@ -154,7 +154,7 @@ python3.lib;%(AdditionalDependencies) - C:\Python27\libs;C:\Users\zhaoxinfeng.evan\AppData\Local\Programs\Python\Python37\Libs;%(AdditionalLibraryDirectories) + C:\Python311\libs;%(AdditionalLibraryDirectories) true Console true @@ -167,9 +167,6 @@ - - - diff --git a/vs2008.x86/ffpython.vcxproj.user b/vs2008.x86/ffpython.vcxproj.user new file mode 100644 index 0000000..f2acd6d --- /dev/null +++ b/vs2008.x86/ffpython.vcxproj.user @@ -0,0 +1,13 @@ + + + + PATH=C:\Python311%3b$(PATH) + WindowsLocalDebugger + $(OutDir) + + + PATH=C:\Python311%3b$(PATH) + WindowsLocalDebugger + $(OutDir) + + \ No newline at end of file