The solution to my problem is a combination of boost::serialization and boost::shared_ptr.
Rather than holding refs to the contained shared objects, if the objects are share_ptr, then serialization will do the correct thing. For example, I have struct boost_uniform_int_wrap { boost::shared_ptr<rng_t> rng_obj; boost::uniform_int<> gen; boost_uniform_int_wrap (boost::shared_ptr<rng_t> _rng_obj, int min, int max) : rng_obj (_rng_obj), gen (min, max) {} ... struct uniform_int_pickle_suite : bp::pickle_suite { static bp::tuple getinitargs (boost_uniform_int_wrap const& gen) { return bp::make_tuple (gen.rng_obj, gen.gen.min(), gen.gen.max()); } }; Also, I have modified mersenne_twister to make it serializable (very simple to add). Then to make mersenne_twister pickleable: 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; } }; Now: from boost_rand import rng, normal from sys import getrefcount rng1 = rng() print getrefcount(rng1) n1 = normal (rng1, 1, 0) print getrefcount(rng1) n2 = normal (rng1, 1, 0) print getrefcount(rng1) from cPickle import dumps, loads rng2, n3, n4 = loads (dumps ((rng1, n1, n2), -1)) In [10]: ## working on region in file /usr/tmp/python-18983NT.py... 2 3 4 In [11]: rng2 Out[11]: <boost_rand.rng at 0x307c838> In [12]: n3.rng Out[12]: <boost_rand.rng at 0x307c838> In [13]: n4.rng Out[13]: <boost_rand.rng at 0x307c838> _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig