From adfac77e6118edbae4040ca61c8b5cecf2474292 Mon Sep 17 00:00:00 2001 From: marioalexis Date: Mon, 6 Jun 2022 20:28:58 -0300 Subject: [PATCH] Base: Add function to get Python object types for SWIG interfaces --- src/Base/Interpreter.cpp | 35 ++++++++++++++++++++++++++--------- src/Base/Interpreter.h | 1 + src/Base/swigpyrun.inl | 28 ++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/src/Base/Interpreter.cpp b/src/Base/Interpreter.cpp index 97be921287..b3e608eff2 100644 --- a/src/Base/Interpreter.cpp +++ b/src/Base/Interpreter.cpp @@ -825,7 +825,12 @@ int getSWIGVersionFromModule(const std::string& module) } #if (defined(HAVE_SWIG) && (HAVE_SWIG == 1)) -namespace Swig_python { extern int createSWIGPointerObj_T(const char* TypeName, void* obj, PyObject** ptr, int own); } +namespace Swig_python { +extern int createSWIGPointerObj_T(const char* TypeName, void* obj, PyObject** ptr, int own); +extern int convertSWIGPointerObj_T(const char* TypeName, PyObject* obj, void** ptr, int flags); +extern void cleanupSWIG_T(const char* TypeName); +extern int getSWIGPointerTypeObj_T(const char* TypeName, PyTypeObject** ptr); +} #endif PyObject* InterpreterSingleton::createSWIGPointerObj(const char* Module, const char* TypeName, void* Pointer, int own) @@ -850,10 +855,6 @@ PyObject* InterpreterSingleton::createSWIGPointerObj(const char* Module, const c throw Base::RuntimeError("No SWIG wrapped library loaded"); } -#if (defined(HAVE_SWIG) && (HAVE_SWIG == 1)) -namespace Swig_python { extern int convertSWIGPointerObj_T(const char* TypeName, PyObject* obj, void** ptr, int flags); } -#endif - bool InterpreterSingleton::convertSWIGPointerObj(const char* Module, const char* TypeName, PyObject* obj, void** ptr, int flags) { int result = 0; @@ -876,10 +877,6 @@ bool InterpreterSingleton::convertSWIGPointerObj(const char* Module, const char* throw Base::RuntimeError("No SWIG wrapped library loaded"); } -#if (defined(HAVE_SWIG) && (HAVE_SWIG == 1)) -namespace Swig_python { extern void cleanupSWIG_T(const char* TypeName); } -#endif - void InterpreterSingleton::cleanupSWIG(const char* TypeName) { PyGILStateLocker locker; @@ -889,3 +886,23 @@ void InterpreterSingleton::cleanupSWIG(const char* TypeName) (void)TypeName; #endif } + +PyTypeObject* InterpreterSingleton::getSWIGPointerTypeObj(const char* Module, const char* TypeName) +{ + int result = 0; + PyTypeObject* proxy = nullptr; + PyGILStateLocker locker; + (void)Module; +#if (defined(HAVE_SWIG) && (HAVE_SWIG == 1)) + result = Swig_python::getSWIGPointerTypeObj_T(TypeName, &proxy); +#else + (void)TypeName; + result = -1; // indicates error +#endif + + if (result == 0) + return proxy; + + // none of the SWIG's succeeded + throw Base::RuntimeError("No SWIG wrapped library loaded"); +} diff --git a/src/Base/Interpreter.h b/src/Base/Interpreter.h index c9ce6274c6..a4db52107d 100644 --- a/src/Base/Interpreter.h +++ b/src/Base/Interpreter.h @@ -283,6 +283,7 @@ public: PyObject* createSWIGPointerObj(const char* Modole, const char* TypeName, void* Pointer, int own); bool convertSWIGPointerObj(const char* Module, const char* TypeName, PyObject* obj, void** ptr, int flags); void cleanupSWIG(const char* TypeName); + PyTypeObject* getSWIGPointerTypeObj(const char* Module, const char* TypeName); //@} /** @name methods for debugging facility diff --git a/src/Base/swigpyrun.inl b/src/Base/swigpyrun.inl index dcfea7e896..172198820d 100644 --- a/src/Base/swigpyrun.inl +++ b/src/Base/swigpyrun.inl @@ -51,6 +51,7 @@ int convertSWIGPointerObj_T(const char* TypeName, PyObject* obj, void** ptr, int swig_type_info * swig_type = nullptr; swig_type = SWIG_TypeQuery(TypeName); + if (!swig_type) throw Base::RuntimeError("Cannot find type information for requested type"); @@ -101,3 +102,30 @@ void cleanupSWIG_T(const char* TypeName) // Run garbage collector PyGC_Collect(); } + +int getSWIGPointerTypeObj_T(const char* TypeName, PyTypeObject** ptr) +{ + swig_module_info *module = SWIG_GetModule(nullptr); + if (!module) + return 1; + + swig_type_info * swig_type = nullptr; + SwigPyClientData* clientData = nullptr; + PyTypeObject* pyType = nullptr; + swig_type = SWIG_TypeQuery(TypeName); + if (swig_type) + clientData = static_cast(swig_type->clientdata); + + if (clientData) + pyType = reinterpret_cast(clientData->newargs); + + if (!pyType) { + std::stringstream str; + str << "SWIG: Cannot find type information for requested type: " << TypeName; + throw Base::RuntimeError(str.str()); + } + + *ptr = pyType; + + return 0; +}