On 12/6/2012 2:18 AM, Giuseppe Corbelli
wrote:
On 06/12/2012 01:17, Jaedyn K. Draper wrote:Before I go into the explanation here, I'll say that your suggestion actually gave me what I wanted. Thanks! Still, I'll explain what I wanted, since you asked. Who knows? Maybe there's an even better way to implement it, though this way is working fantastically and seamlessly. Ok, here's some theoretical example code of what I *want* to happen. (Far simplified from the actual use case, but should be easier to understand this way.) On the C++ side, I have a generic class that has some base information in it: class MyObj { int SomeInt; std::string SomeStr; }; This class is exposed to Python using boost.python. (I won't post that code here since it's basic enough and is working fine for me.) On the python side, I'd like to have, for example, two events that expect a MyObj as their first argument: def OnFirstEvent(obj): obj.SomeList = [1, 2, 3, 4, 5] print obj.SomeList def OnSecondEvent(obj): obj.SomeList += [6, 7, 8, 9, 10] print obj.SomeList If, in the C++, I then call those like this: void MyFunc() { MyObj obj; globals["OnFirstEvent"](ptr(&obj)); globals["OnSecondEvent"](ptr(&obj)); } The first event will work fine, and print out [1, 2, 3, 4, 5] as expected. When the second event is called, the information from the first event is lost, as it isn't part of the base C++ object so there's nothing on that object that stores it. So it throws an AttributeError. My idea to fix that was to do this: class MyObj { public: MyObj() : self(ptr(this)) {} boost::python::object *GetPyObj(){ return &PyObj; } private: int SomeInt; std::string SomeStr; boost::python::object PyObj; }; void MyFunc() { MyObj obj; globals["OnFirstEvent"](ptr(obj.GetPyObj())); globals["OnSecondEvent"](ptr(obj.GetPyObj())); } My thinking was that by keeping the object instance within the class in this way, I'd be able to make the new SomeList value persist. But I can't call the function by passing an actual python object, only by passing a C++ object that's been extended, because it tries to convert that object to an object. Using a std::map as a pseudo-__dict__ analog as you suggested - combined with overloading __getattr__ and __setattr__ to work with that map instead of the default __dict__ - worked perfectly for this! It's not exactly what I had in mind but really I think it's probably a better solution than having the class hold an object pointing to itself. This is a MUCH better solution than what I'd come up with previously, which was working the way I wanted it to, but was pretty hacky and implemented in the python rather than the C++, which I wanted to avoid if possible. Thanks for the suggestion! |
_______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig