diff options
author | David Wagner <david.wagner@intel.com> | 2015-01-21 15:56:54 +0100 |
---|---|---|
committer | David Wagner <david.wagner@intel.com> | 2015-01-28 20:02:46 +0100 |
commit | 171814cc5a36305066b17ec1f55f15a01adfdbf8 (patch) | |
tree | 1fd3067c6146ae37b5f507c2ac96a7bd627c4029 /bindings | |
parent | f01cb8127ce34f758a043b4ef1c12695035bc632 (diff) | |
download | external_parameter-framework-171814cc5a36305066b17ec1f55f15a01adfdbf8.zip external_parameter-framework-171814cc5a36305066b17ec1f55f15a01adfdbf8.tar.gz external_parameter-framework-171814cc5a36305066b17ec1f55f15a01adfdbf8.tar.bz2 |
bindings: bind ILogger and setLogger()
This will allow users of the parameter-framework bindings to set a logger;
without it, the parameter-framework wasn't able to log anything.
Some SWIG features and workarounds must be activated in order to:
- Support nested classes;
- Derive bound classes and allow C++ to call back the user-created objects;
- Properly handle exceptions that may be raised upon errors happening on the
user side.
Change-Id: I955152a4658eff3307ad595f175f2624a3acfa8c
Signed-off-by: David Wagner <david.wagner@intel.com>
Diffstat (limited to 'bindings')
-rw-r--r-- | bindings/python/Android.mk | 6 | ||||
-rw-r--r-- | bindings/python/CMakeLists.txt | 10 | ||||
-rw-r--r-- | bindings/python/pfw.i | 38 | ||||
-rwxr-xr-x | bindings/python/sample.py | 19 |
4 files changed, 68 insertions, 5 deletions
diff --git a/bindings/python/Android.mk b/bindings/python/Android.mk index 2cfd13d..296d4bc 100644 --- a/bindings/python/Android.mk +++ b/bindings/python/Android.mk @@ -48,7 +48,11 @@ LOCAL_C_INCLUDES := \ # The 'unused-but-set-variable' warning must be disabled because SWIG generates # files that do not respect that constraint. -LOCAL_CFLAGS := -Wno-unused-but-set-variable -fexceptions +# '-DSWIG_PYTHON_SILENT_MEMLEAK' is needed because the "memleak" warning +# pollutes the standard output. At the time of writing, the only warning is +# spurious anyway, as it relates to "ILogger *" which is an abstract +# class/interface class and as such cannot be destroyed. +LOCAL_CFLAGS := -Wno-unused-but-set-variable -fexceptions -DSWIG_PYTHON_SILENT_MEMLEAK # Undefined symbols will be resolved at runtime LOCAL_ALLOW_UNDEFINED_SYMBOLS := true diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index 535c920..e9016b1 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -48,9 +48,13 @@ endif(NOT PYTHONLIBS_FOUND) include_directories(${PROJECT_SOURCE_DIR}/parameter/include ${PYTHON_INCLUDE_DIRS}) -# Add some exceptions because files generated by SWIG are not -# "-Wextra"-compliant -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-but-set-variable") +# The 'unused-but-set-variable' warning must be disabled because SWIG generates +# files that do not respect that contraint. +# '-DSWIG_PYTHON_SILENT_MEMLEAK' is needed because the "memleak" warning +# pollutes the standard output. At the time of writing, the only warning is +# spurious anyway, as it relates to "ILogger *" which is an abstract +# class/interface class and as such cannot be destroyed. +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-but-set-variable -DSWIG_PYTHON_SILENT_MEMLEAK") install(TARGETS _PyPfw LIBRARY DESTINATION lib) diff --git a/bindings/python/pfw.i b/bindings/python/pfw.i index c029d13..da01cdc 100644 --- a/bindings/python/pfw.i +++ b/bindings/python/pfw.i @@ -27,7 +27,22 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -%module PyPfw +// The generated python module will be named "PyPfw" +// the "directors" feature is used to derive Python classes and make them look +// like derived C++ classes (calls to virtual methods will be properly +// forwarded to Python) - only on classes for which is it specified, see +// ILogger below.. +%module(directors="1") PyPfw + +%feature("director:except") { + if ($error != NULL) { + throw Swig::DirectorMethodException(); + } +} +%exception { + try { $action } + catch (Swig::DirectorException &e) { SWIG_fail; } +} %include "std_string.i" %include "std_vector.i" @@ -63,6 +78,8 @@ public: bool start(std::string& strError); + void setLogger(ILogger* pLogger); + ISelectionCriterionTypeInterface* createSelectionCriterionType(bool bIsInclusive); ISelectionCriterionInterface* createSelectionCriterion(const std::string& strName, const ISelectionCriterionTypeInterface* pSelectionCriterionType); @@ -155,6 +172,25 @@ public: %clear std::string& strResult; }; +// SWIG nested class support is not complete - cf. +// http://swig.org/Doc2.0/SWIGPlus.html#SWIGPlus_nested_classes +// This link also explains how to trick SWIG and pretend that +// ILogger is a toplevel class (whereas it actually is an inner class of +// CParameterMgrFullConnector +// Logger interface +%feature("director") ILogger; +%nestedworkaround CParameterMgrFullConnector::ILogger; +class ILogger +{ + public: + virtual void log(bool bIsWarning, const std::string& strLog) = 0; + protected: + virtual ~ILogger() {} +}; +%{ +typedef CParameterMgrFullConnector::ILogger ILogger; +%} + class ISelectionCriterionTypeInterface { %{ diff --git a/bindings/python/sample.py b/bindings/python/sample.py index f33ddeb..1208fc9 100755 --- a/bindings/python/sample.py +++ b/bindings/python/sample.py @@ -29,9 +29,28 @@ import PyPfw import sys +import logging + +class MyLogger(PyPfw.ILogger): + def __init__(self): + # Calling the base constructor is necessary: if you don't, MyLogger + # won't be recognised as a derived class of PyPfw.ILogger + super(MyLogger, self).__init__() + + def log(self, is_warning, log): + log_func = logging.warning if is_warning else logging.info + log_func(log) + + +logging.root.setLevel(logging.INFO) pfw = PyPfw.ParameterFramework(sys.argv[1]) +# warning: don't pass MyLogger() directly as argument to setLogger() or it will +# be garbage collected +mylogger = MyLogger() +pfw.setLogger(mylogger); + moodType = pfw.createSelectionCriterionType(False) for numerical, literal in enumerate(["mad", "sad", "glad"]): moodType.addValuePair(numerical, literal) |