0

调用方法时会抛出错误。

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代码?

这是在 PyGMO python 库中,它是 PyGMO 1.7 版本,但更新版本不包含必要的问题。

编辑(添加导致问题的代码):

from PyGMO import *
prob = problem.cassini_1()
prob._objfun_impl((1.0,1.0))

我意识到元组不会满足论点,但是我不知道会怎样

4

1 回答 1

0

从这个出色的答案中大量借鉴:将 Python 列表输入到使用 Boost Python 接收向量的函数中,我创建了以下MVCE

Live On Coliru

#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
于 2018-04-05T15:36:30.193 回答