При вызове метода выдается ошибка.
Traceback (most recent call last):
File "./test.py", line 10, in <module>
print prob._objfun_impl(data1)
Boost.Python.ArgumentError: Python argument types in
_base._objfun_impl(cassini_1, tuple)
did not match C++ signature:
_objfun_impl(pagmo::problem::python_base {lvalue}, std::vector<double,
std::allocator<double> >)
Как мне написать код Python, который бы удовлетворял аргументам метода?
Это находится в библиотеке Python PyGMO, это версия PyGMO 1.7, но обновленная версия не содержит необходимых проблем.
Редактировать (добавлен код причины проблемы):
from PyGMO import *
prob = problem.cassini_1()
prob._objfun_impl((1.0,1.0))
Я понимаю, что кортеж не будет удовлетворять аргументам, однако я не знаю, что будет
Занят тяжело из этого превосходного ответа: Подача списка Python в функцию с вектором с помощью Boost Python Я создал следующее MVCE:
#define BOOST_NO_AUTO_PTR
#include <boost/python/class.hpp>
#include <boost/python/def.hpp>
#include <boost/python/stl_iterator.hpp>
#include <boost/python/module.hpp>
#include <vector>
namespace pagmo { namespace problem {
struct python_base {
std::string _objfun_impl(std::vector<double> values) {
return "Values: " + std::to_string(values.size());
}
};
struct cassini_1 : python_base { };
} }
/// @brief Type that allows for registration of conversions from
/// python iterable types.
struct iterable_converter {
/// @note Registers converter from a python interable type to the
/// provided type.
template <typename Container> iterable_converter& from_python() {
boost::python::converter::registry::push_back(
&iterable_converter::convertible,
&iterable_converter::construct<Container>,
boost::python::type_id<Container>());
// Support chaining.
return *this;
}
/// @brief Check if PyObject is iterable.
static void* convertible(PyObject* object) {
return PyObject_GetIter(object) ? object : NULL;
}
/// @brief Convert iterable PyObject to C++ container type.
///
/// Container Concept requirements:
///
/// * Container::value_type is CopyConstructable.
/// * Container can be constructed and populated with two iterators.
/// I.e. Container(begin, end)
template <typename Container>
static void construct(
PyObject* object,
boost::python::converter::rvalue_from_python_stage1_data* data) {
namespace python = boost::python;
// Object is a borrowed reference, so create a handle indicting it is
// borrowed for proper reference counting.
python::handle<> handle(python::borrowed(object));
// Obtain a handle to the memory block that the converter has allocated
// for the C++ type.
typedef python::converter::rvalue_from_python_storage<Container>
storage_type;
void* storage = reinterpret_cast<storage_type*>(data)->storage.bytes;
typedef python::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(python::object(handle)), // begin
iterator()); // end
data->convertible = storage;
}
};
using namespace boost::python;
BOOST_PYTHON_MODULE(sotest) {
iterable_converter()
.from_python<std::vector<double> >()
;
class_<pagmo::problem::cassini_1>("cassini_1")
.def("_objfun_impl", &pagmo::problem::cassini_1::_objfun_impl)
;
}
Сборка с:
g++ -fPIC -std=c++14 -Os -shared -o sotest.so main.cpp -lpython2.7 -lboost_python -I /usr/include/python2.7
Тест со скриптом Python:
#!/usr/bin/env python
import sotest
prob = sotest.cassini_1()
print (prob._objfun_impl([1,2,3]))
values = [1,2,3];
values.extend([3.1415926, 42]);
print (prob._objfun_impl(values))
Печать
Values: 3
Values: 5
Других решений пока нет …