[英]Boost.Serialization and Boost.Python two-way pickle
I have a C++ library that uses Boost.Serialization.我有一个使用 Boost.Serialization 的 C++ 库。 I'm creating Python bindings for this library using Boost.Python.我正在使用 Boost.Python 为这个库创建 Python 绑定。 It's fairly clear how to make a pickle suite for Boost.Python that uses Boost.Serialization (save to a string using Boost.Serialization, and return that string to Python).如何为使用 Boost.Serialization 的 Boost.Python 创建一个 pickle 套件(使用 Boost.Serialization 保存到一个字符串,然后将该字符串返回给 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.我想要的是相反的:给定一个boost::python::object
,我想要一个serialize(...)
函数来调用 Python 的pickle.dumps()
函数并序列化结果字符串。 (Imagine an std::vector<boost::python::object>
. As I serialize this vector, Boost.Serialization would call the auxiliary serialize()
function.) Is this possible? (想象一个std::vector<boost::python::object>
。当我序列化这个向量时,Boost.Serialization 会调用辅助serialize()
函数。)这可能吗? Better yet, is it possible to use cPickle
and bypass giving the control to the Python interpreter?更好的是,是否可以使用cPickle
并绕过将控制权交给 Python 解释器?
Here is the code I use to pickle/unpickle instance of boost::mersenne_twister这是我用来pickle/unpickle 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.如果您的对象是本机 Python 对象,那么 pickle.dumps() 可以解决问题。
In the other hand, if you have a std::vector, then you are mixing c++ and python.另一方面,如果你有一个 std::vector,那么你就是在混合 c++ 和 python。 For that you will need to register the std::vector like:为此,您需要注册 std::vector ,例如:
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. TL;DR:改用 boost::python::list 并在其上调用 dump。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.