summaryrefslogtreecommitdiffstats
path: root/bindings
diff options
context:
space:
mode:
authorDavid Wagner <david.wagner@intel.com>2015-01-21 15:56:54 +0100
committerDavid Wagner <david.wagner@intel.com>2015-01-28 20:02:46 +0100
commit171814cc5a36305066b17ec1f55f15a01adfdbf8 (patch)
tree1fd3067c6146ae37b5f507c2ac96a7bd627c4029 /bindings
parentf01cb8127ce34f758a043b4ef1c12695035bc632 (diff)
downloadexternal_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.mk6
-rw-r--r--bindings/python/CMakeLists.txt10
-rw-r--r--bindings/python/pfw.i38
-rwxr-xr-xbindings/python/sample.py19
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)