Boost.Serialization and Boost.Python two-way pickle
I have a C++ library that uses Boost.Serialization. I'm creating Python bindings for this library using Boost.Python. It's fairly clear how to make a pickle suite for Boost.Python that uses开发者_如何学JAVA Boost.Serialization (save to a string using Boost.Serialization, and return that string to Python).
What I want is the reverse: given a boost::python::object
, I want to have a serialize(...)
function that would call Python's pickle.dumps()
function and serialize the resulting string. (Imagine an std::vector<boost::python::object>
. As I serialize this vector, Boost.Serialization would call the auxiliary serialize()
function.) Is this possible? Better yet, is it possible to use cPickle
and bypass giving the control to the Python interpreter?
Here is the code I use to pickle/unpickle instance of boost::mersenne_twister
typedef boost::mt19937 rng_t;
struct mt_pickle_suite : bp::pickle_suite {
static bp::object getstate (const rng_t& rng) {
std::ostringstream os;
boost::archive::binary_oarchive oa(os);
oa << rng;
return bp::str (os.str());
}
static void
setstate(rng_t& rng, bp::object entries) {
bp::str s = bp::extract<bp::str> (entries)();
std::string st = bp::extract<std::string> (s)();
std::istringstream is (st);
boost::archive::binary_iarchive ia (is);
ia >> rng;
}
};
If your object is a native python object, then pickle.dumps() will do the trick.
In the other hand, if you have a std::vector, then you are mixing c++ and python. For that you will need to register the std::vector like:
using PyVec = std::vector<boost::python::object>;
boost::python::_class<PyVec, boost::noncopyable>
("PyVec", "My vector of PyObjects", boost::python::init<>() )
.enable_pickling()
.def_pickle( py_vec_pickle_suit() );
Then, of course you will need to define a pickle suit. But that is too cumbersome.
TL;DR: Use boost::python::list instead and call dump over it.
精彩评论