Привет я использую Python для запуска класса cpp, который использует Boost Python для преобразования в Python для использования. в то же время у меня есть требование выбирать классы Python, использующие класс Cpp с поддержкой Python.
Так что я сделал, чтобы добавить enable_picking () к определению примера класса следующим образом:
class_<pform::base::Price>("Price", init<double>())
.def(self == self)
.def(self_ns::str(self_ns::self)) // __str__
.def("get_value", &pform::base::Price::get_value)
это делает класс маринованным. Тем не менее, я получаю эту ошибку, когда откройте ее.
Boost.Python.ArgumentError: Python argument types in
Price.__init__(Price)
did not match C++ signature:
__init__(_object*, double)
Так чего здесь не хватает?
Немного поздно, но я нашел соответствующую документацию для этого:
http://www.boost.org/doc/libs/1_64_0/libs/python/doc/html/reference/topics/pickle_support.html
Интерфейс Pickle
На пользовательском уровне рассол Boost.Python
Интерфейс включает в себя три специальных метода:
__getinitargs__
Когда экземпляр класса расширения Boost.Python засолен, сборщик проверяет, имеет ли экземпляр__getinitargs__
метод. Этот метод должен возвращать кортеж Python (это наиболее удобно
использоватьboost::python::tuple
). Когда экземпляр восстанавливается
unpickler, содержимое этого кортежа используется в качестве аргументов для
конструктор класса. Если__getinitargs__
не определено, pickle.load
вызовет конструктор (__init__
) без аргументов; то есть
объект должен быть конструируемым по умолчанию.
__getstate__
Когда экземпляр класса расширения Boost.Python засолен, сборщик проверяет, имеет ли экземпляр__getstate__
метод.
Этот метод должен возвращать объект Python, представляющий состояние
экземпляр.
__setstate__
Когда экземпляр класса расширения Boost.Python восстанавливается с помощью средства выбора (pickle.load), он сначала создается с использованием
результат__getinitargs__
в качестве аргументов (см. выше). впоследствии
unpickler проверяет, имеет ли новый экземпляр__setstate__
метод. Если
Итак, этот метод вызывается с результатом__getstate__
(Питон
объект) в качестве аргумента.Три специальных метода, описанных выше, могут
быть.def()
редактируется индивидуально пользователем. Тем не менее, Boost.Python обеспечивает
простой в использовании интерфейс высокого уровня через
boost::python::pickle_suite
класс, который также обеспечивает согласованность:
__getstate__
а также__setstate__
должны быть определены как пары. Использование этого интерфейса демонстрируется следующими примерами.
В вашем конкретном примере класс не является конструируемым по умолчанию, так как он нуждается в double
аргумент (который я предполагаю, является «значением»). Чтобы обернуть его для Python, вам также необходимо определить:
.def("__getinitargs__", +[](pform::base::Price const& self){
return boost::python::make_tuple(self.get_value());
})
Теперь Boost Python инициализирует ваш класс, используя «значение»; вместо вызова конструктора по умолчанию (pform::base::Price()
).
Других решений пока нет …