]> sigrok.org Git - libsigrok.git/blobdiff - bindings/python/sigrok/core/classes.i
python: Fix the build for Python >= 3.
[libsigrok.git] / bindings / python / sigrok / core / classes.i
index 7a6eb22ba3789ecb54f8c8d6b745831571f4a497..93e03ef29e5203d9e45035a22da2aa7e93815fc8 100644 (file)
@@ -24,7 +24,7 @@ Introduction
 ------------
 
 The pysigrok API provides an object-oriented Python interface to the
-functionality in libsigrok. It is built on top of the sigrok++ C++ API.
+functionality in libsigrok. It is built on top of the libsigrokcxx C++ API.
 
 Getting started
 ---------------
@@ -45,8 +45,11 @@ which provides access to the error code and description."
 %module(docstring=DOCSTRING) classes
 
 %{
+#include <stdio.h>
 #include <pygobject.h>
+#include <numpy/arrayobject.h>
 
+PyObject *PyGObject_lib;
 PyObject *GLib;
 PyTypeObject *IOChannel;
 PyTypeObject *PollFD;
@@ -62,10 +65,25 @@ typedef guint pyg_flags_type;
 %}
 
 %init %{
-    pygobject_init(-1, -1, -1);
+    PyGObject_lib = pygobject_init(-1, -1, -1);
+    if (!PyGObject_lib)
+        fprintf(stderr, "pygobject initialization failed.\n");
     GLib = PyImport_ImportModule("gi.repository.GLib");
+    /*
+     * This check can't save us if the import fails, but at least it gives us
+     * a starting point to trace the issue versus straight out crashing.
+     */
+    if (!GLib) {
+        fprintf(stderr, "Import of gi.repository.GLib failed.\n");
+#if PY_VERSION_HEX >= 0x03000000
+        return NULL;
+#else
+        return;
+#endif
+    }
     IOChannel = (PyTypeObject *) PyObject_GetAttrString(GLib, "IOChannel");
     PollFD = (PyTypeObject *) PyObject_GetAttrString(GLib, "PollFD");
+    import_array();
 %}
 
 /* Map file objects to file descriptors. */
@@ -211,7 +229,7 @@ typedef guint pyg_flags_type;
     if (!PyCallable_Check($input))
         SWIG_exception(SWIG_TypeError, "Expected a callable Python object");
 
-    $1 = [=] (const sigrok::LogLevel *loglevel, string message) {
+    $1 = [=] (const sigrok::LogLevel *loglevel, std::string message) {
         auto gstate = PyGILState_Ensure();
 
         auto log_obj = SWIG_NewPointerObj(
@@ -351,7 +369,7 @@ typedef guint pyg_flags_type;
 
 %{
 
-#include "libsigrok/libsigrok.hpp"
+#include "libsigrokcxx/libsigrokcxx.hpp"
 
 /* Convert from a Python dict to a std::map<std::string, std::string> */
 std::map<std::string, std::string> dict_to_map_string(PyObject *dict)
@@ -446,6 +464,7 @@ std::map<std::string, Glib::VariantBase> dict_to_map_options(PyObject *dict,
 %}
 
 /* Ignore these methods, we will override them below. */
+%ignore sigrok::Analog::data;
 %ignore sigrok::Driver::scan;
 %ignore sigrok::InputFormat::create_input;
 %ignore sigrok::OutputFormat::create_output;
@@ -573,3 +592,23 @@ std::map<std::string, Glib::VariantBase> dict_to_map_options(PyObject *dict,
         $self->config_set(key, python_to_variant_by_key(input, key));
     }
 }
+
+/* Return NumPy array from Analog::data(). */
+%extend sigrok::Analog
+{
+    PyObject * _data()
+    {
+        int nd = 2;
+        npy_intp dims[2];
+        dims[0] = $self->channels().size();
+        dims[1] = $self->num_samples();
+        int typenum = NPY_FLOAT;
+        void *data = $self->data_pointer();
+        return PyArray_SimpleNewFromData(nd, dims, typenum, data);
+    }
+
+%pythoncode
+{
+    data = property(_data)
+}
+}