diff options
Diffstat (limited to 'host/python/pyuhd.cpp')
| -rw-r--r-- | host/python/pyuhd.cpp | 179 | 
1 files changed, 24 insertions, 155 deletions
| diff --git a/host/python/pyuhd.cpp b/host/python/pyuhd.cpp index e0f35d929..16badbe8c 100644 --- a/host/python/pyuhd.cpp +++ b/host/python/pyuhd.cpp @@ -1,29 +1,21 @@  //  // Copyright 2017-2018 Ettus Research, a National Instruments Company +// Copyright 2019 Ettus Research, a National Instruments Brand  //  // SPDX-License-Identifier: GPL-3.0-or-later  // -#include <boost/shared_ptr.hpp> -#include <boost/python.hpp> -#include <boost/python/stl_iterator.hpp> -#include <boost/python/suite/indexing/vector_indexing_suite.hpp> - -/* -This solution was adapted from an Issue posted to the Boost.Python Github. -https://github.com/boostorg/python/pull/159/files -*/ -#if (BOOST_VERSION >= 106400) && (BOOST_VERSION < 106600) -#warning overriding broken boost python implementation of BOOST_PYTHON_MODULE_INIT -#  define BOOST_PYTHON_MODULE_INIT(name)                       \ -  void BOOST_PP_CAT(init_module_,name)();                      \ -extern "C" BOOST_SYMBOL_EXPORT _BOOST_PYTHON_MODULE_INIT(name) -#endif +#include <pybind11/pybind11.h>  #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION  #include <numpy/arrayobject.h> -namespace bp = boost::python; +namespace py = pybind11; + +// Allow boost::shared_ptr<T> to be a holder class of an object (PyBind11 +// supports std::shared_ptr and std::unique_ptr out of the box) +#include <boost/shared_ptr.hpp> +PYBIND11_DECLARE_HOLDER_TYPE(T, boost::shared_ptr<T>);  #include "stream_python.hpp" @@ -40,81 +32,6 @@ namespace bp = boost::python;  #include "usrp/subdev_spec_python.hpp"  #include "usrp/multi_usrp_python.hpp" -// Converter for std::vector / std::list arguments from python iterables -struct iterable_converter -{ -    template <typename Container> -    iterable_converter& from_python() -    { -        bp::converter::registry::push_back( -            &iterable_converter::convertible, -            &iterable_converter::construct<Container>, -            bp::type_id<Container>() -        ); -        return *this; -    } - -    static void* convertible(PyObject* object) -    { -        return PyObject_GetIter(object) ? object : NULL; -    } - -    template <typename Container> -    static void construct( -        PyObject* object, -        bp::converter::rvalue_from_python_stage1_data* data) -    { -        // Object is a borrowed reference, so create a handle indicting it is -        // borrowed for proper reference counting. -        bp::handle<> handle(bp::borrowed(object)); - -        // Obtain a handle to the memory block that the converter has -        // allocated for the C++ type. -        typedef bp::converter::rvalue_from_python_storage<Container> storage_type; - -        void* storage = reinterpret_cast<storage_type*>(data)->storage.bytes; -        typedef bp::stl_input_iterator<typename Container::value_type> iterator; - -        // Allocate the C++ type into the converter's memory block, and assign -        // its handle to the converter's convertible variable.  The C++ -        // container is populated by passing the begin and end iterators of -        // the python object to the container's constructor. -        new (storage) Container( -          iterator(bp::object(handle)), // begin -          iterator()                    // end -        ); - -        data->convertible = storage; -    } -}; - -template<typename Dtype1, typename Dtype2> -struct uhd_to_python_dict -{ -    static PyObject* convert(uhd::dict<Dtype1, Dtype2> const& input_dict) -    { -        bp::dict py_dict; -        for (const auto& key: input_dict.keys()){ -            py_dict[key] = input_dict[key]; -        } -        return bp::incref(py_dict.ptr()); -    } - -}; - -template<typename Container> -struct iterable_to_python_list -{ -    static PyObject* convert(Container const& input) -    { -        bp::list py_list; -        for (const auto& element: input){ -            py_list.append(element); -        } -        return bp::incref(py_list.ptr()); -    } -}; -  // We need this hack because import_array() returns NULL  // for newer Python versions.  // This function is also necessary because it ensures access to the C API @@ -132,80 +49,32 @@ void init_numpy()  }  #endif -BOOST_PYTHON_MODULE(libpyuhd) +PYBIND11_MODULE(libpyuhd, m)  {      // Initialize the numpy C API      // (otherwise we will see segmentation faults)      init_numpy(); -    bp::object package = bp::scope(); -    package.attr("__path__") = "libpyuhd"; - -    // Declare converters -    iterable_converter() -        .from_python<std::vector<double> >() -        .from_python<std::vector<int> >() -        .from_python<std::vector<size_t> >() -        ; - -    bp::to_python_converter< -        uhd::dict<std::string, std::string>, -        uhd_to_python_dict<std::string, std::string>, false >(); -    bp::to_python_converter< -        std::vector<std::string>, -        iterable_to_python_list<std::vector<std::string> >, false >(); -      // Register types submodule -    { -        bp::object types_module( -            bp::handle<>(bp::borrowed(PyImport_AddModule("libpyuhd.types"))) -        ); -        bp::scope().attr("types") = types_module; -        bp::scope io_scope = types_module; - -        bp::implicitly_convertible<std::string, uhd::device_addr_t>(); - -        export_types(); -        export_time_spec(); -        export_spi_config(); -        export_metadata(); -        export_sensors(); -        export_tune(); +    auto types_module = m.def_submodule("types", "UHD Types"); -        // Declare some more converters -        iterable_converter() -            .from_python<std::vector<uhd::device_addr_t>>() -            ; - -        bp::to_python_converter< -            std::vector<uhd::device_addr_t>, -            iterable_to_python_list<std::vector<uhd::device_addr_t>>, false >(); -    } +    export_types(types_module); +    export_time_spec(types_module); +    export_spi_config(types_module); +    export_metadata(types_module); +    export_sensors(types_module); +    export_tune(types_module);      // Register usrp submodule -    { -        bp::object usrp_module( -            bp::handle<>(bp::borrowed(PyImport_AddModule("libpyuhd.usrp"))) -        ); -        bp::scope().attr("usrp") = usrp_module; -        bp::scope io_scope = usrp_module; - -        export_multi_usrp(); -        export_subdev_spec(); -        export_dboard_iface(); -        export_fe_connection(); -        export_stream(); -    } +    auto usrp_module = m.def_submodule("usrp", "USRP Objects"); +    export_multi_usrp(usrp_module); +    export_subdev_spec(usrp_module); +    export_dboard_iface(usrp_module); +    export_fe_connection(usrp_module); +    export_stream(usrp_module);      // Register filters submodule -    { -        bp::object filters_module( -            bp::handle<>(bp::borrowed(PyImport_AddModule("libpyuhd.filters"))) -        ); -        bp::scope().attr("filters") = filters_module; -        bp::scope io_scope = filters_module; - -        export_filters(); -    } +    auto filters_module = m.def_submodule("filters", "Filter Submodule"); +    export_filters(filters_module);  } | 
