0

I have already designed a cpp shared lib and now I want to make a Python wrapper to use it. Everything was working fine, until It was necessary to change the cpp library constructor adding one parameter on it.

I would like to know how reflect this parameter in the wrapper, because the code bellow doesn't work anymore. I have made some changes in the code and now it is like bellow. I am almost sure that the problem is in this line

py::class_<Wrapper>("Wrapper", py::init<>())

but I don't know how to add a parameter here. I tried

py::class_<Wrapper>("Wrapper", py::init<>(const std::string &param))

and also

py::class_<Wrapper>("Wrapper", py::init<const std::string &param>())

but both failed.

EDIT after some comments, I decided to use (without reference)

py::class_<Wrapper>("Wrapper", py::init<const std::string param>())

But I still have the same error message.

wrapper.hpp

#include "mycpplib.hpp"

#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
#include <boost/python/dict.hpp>

namespace py = boost::python;
namespace np = boost::python::numpy;

class Wrapper 
{
    public:

        // change: inclusion of the new parameter
        Wrapper(const std::string &param);

        py::dict function1();
};

wrapper.cpp

#include "wrapper.hpp"

namespace py = boost::python;
namespace np = boost::python::numpy;

// change: inclusion of the new parameter
Wrapper::Wrapper(
    const std::string &param) {
    //do something
}

py::dict
Wrapper::function1() {
    //do something
}

BOOST_PYTHON_MODULE(libwrapper)
{
    Py_Initialize();
    np::initialize();

    py::class_<Wrapper>("Wrapper", py::init<const std::string param1>())
        .def("_function1", &Wrapper::function1)
    ;
}

wrapper.py

import libwrapper

class Wrapper(libwrapper.Wrapper):

    # change: inclusion of the new parameter
    def __init__(self, param):
        libwrapper.Wrapper.__init__(self, param)

    def function1(self):
        return self._function1()

The error is:

/path/wrapper.cpp: In function 'void init_module_libwrapper()':
/path/wrapper.cpp:24:69: error: template argument 1 is invalid
py::class_<Wrapper>("Wrapper", py::init<const std::string param1>())
                                                                 ^
Carlos Ost
  • 492
  • 7
  • 22
  • Side-note: If you don't have Boost otherwise involved, and you're writing new code, [I'd recommend going with `pybind11`](https://stackoverflow.com/q/49653205/364696); the build is easier (since `pybind11` is a header-only library, no compile time or build time library dependencies are involved) and it tends to be "smarter" about binding generation (since it was built to use C++11 type inference features from the beginning). – ShadowRanger Jun 14 '19 at 17:51
  • @ShadowRanger Thank you for you suggestion, but it is not an option to change it now. I need to solve the problem as it is. – Carlos Ost Jun 14 '19 at 17:59
  • String is coming from python and python strings are immutable so you can't pass them by reference. See [here](https://stackoverflow.com/questions/47296287/boost-python-error-when-passing-variable-by-reference-in-a-function) for possible solution. – doqtor Jun 14 '19 at 18:28
  • @doqtor I was excited with the possibility of a solution, but it didn't work either. The error is still `error: template argument 1 is invalid py::class_("Wrapper", py::init())`, but now without the & in `std::string &param1` – Carlos Ost Jun 14 '19 at 18:57

1 Answers1

1

Reanding the boost documentation (https://www.boost.org/doc/libs/1_68_0/libs/python/doc/html/tutorial/tutorial/exposing.html) I found that this:

py::class_<Wrapper>("Wrapper", py::init<const std::string param1>())

Should be written like this:

py::class_<Wrapper>("Wrapper", py::init<const std::string>())

without the parameter name. Just the type

Carlos Ost
  • 492
  • 7
  • 22