[C++-sig] Passing objects between python / c++
Mark Williams
mark at image-engine.com
Mon Oct 23 22:58:10 CEST 2006
I'm having a few problems passing objects in and out of Python/C++ via boost.python, which are probably explained best by the example and test cases below.
I have a trivial class "Base", and some functions which allows reference-counted instances of this class to be stored/retrieved to/from a static variable.
Firstly, I derive class "Derived" from "Base" within Python, and "store" an instance of Derived in the C++ static. When
I then "retrieve" this object in Python I find that it's no longer of type "Derived", but of type "Base":
c = Derived()
store(c)
d = retrieve()
self.assertEqual( type(c), type(d) ) # FAILS
Secondly, I store and then immediately retrieve an instance of "Base". I find that boost returns me a different Python object.
I'm not surprised that this happens, but cannot find a CallPolicy which works:
c = Base()
store(c)
d = retrieve()
self.assert_( c is d ) # FAILS
Is it possible to fix either of these problems by modifiying my boost.python bindings alone?
Thanks in advance,
Mark
////////////////////////////////////////////////
class Base : public RefCounted /* RefCounted is my own implementation of a simple reference counting class */
{
public:
Base() {};
};
typedef boost::intrusive_ptr<Base> BasePtr;
template<typename T>
struct GlobalsTest
{
static boost::intrusive_ptr<T> g_object ;
static boost::intrusive_ptr<T> retrieve()
{
return g_object;
}
static void store( const boost::intrusive_ptr<T> &o)
{
g_object = o;
}
};
BOOST_PYTHON_MODULE(myModule)
{
class_< Base, BasePtr>("Base");
def("store", & GlobalsTest<Base>::store );
def("retrieve", & GlobalsTest<Base>::retrieve );
}
//////////////////////////////////////////////////////////////////////////////////////////////////
import unittest
from myModule import *
class Derived(Base):
def methodInDerived(self):
return 12
class TestBoostPython(unittest.TestCase):
def test1(self):
c = Derived()
self.assertEqual( c.methodInDerived(), 12 )
store(c)
d = retrieve()
self.assertEqual( type(c), type(d) )
self.assert_( c is d )
def test2(self):
c = Base()
store(c)
d = retrieve()
self.assertEqual( type(c), type(d) )
self.assert_( c is d )
if __name__ == "__main__":
unittest.main()
/////////////////////////////////////////////////////////////////////////////////
test1 (__main__.TestBoostPython) ... FAIL
test2 (__main__.TestBoostPython) ... FAIL
======================================================================
FAIL: test1 (__main__.TestBoostPython)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test/boostPython.py", line 19, in test1
self.assertEqual( type(c), type(d) )
AssertionError: <class '__main__.Derived'> != <class 'myModule.Base'>
======================================================================
FAIL: test2 (__main__.TestBoostPython)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test/boostPython.py", line 30, in test2
self.assert_( c is d )
AssertionError
----------------------------------------------------------------------
More information about the Cplusplus-sig
mailing list