T-shirts and SWIGged C

First of all, at Google it's another day, another t-shirt. I added a partial album of Google T-Shirts from this summer so far. I haven't even managed to take pictures of all of em yet.. But on to this SWIGged C thing. I was fighting with another very strange problem in some code I was working on. I'm writing all of my code in Python, but a lot of the things that I need to use are in C++. Conveniently, there is a nifty tool called SWIG that lets someone expose C++ and C objects and methods to "a variety of higher level programming languages" of which Python is one of. (Cool!) So there was some C++ code I needed to use and a quick Python loop later, I thought I had something written that would create all of the C++ backed objects that I needed. Each C++ object had 3 other C++ objects assigned to it in Python. All sounds believable and looked like perfectly good code to me, but something wasn't right. When running it I would get strange core dumps that didn't make any sense, and the 3 people I go to at work to ask Python questions were all baffled. In addition to just crashing, very strange things would happen like when trying to reference an object, I would get back the contents of one of the sub objects of the other objects some of the time and nothing other times. I fought this most of the day, trying wrapper classes, using a create method instead of doing the work in a loop, etc, but nothing seemed to work. I thought it might be an issue with variable scoping, but Python isn't stupid and a variable private to a method is private to that method, etc. After a suggestion from one of the guys I work with, I created a global array and used a counter in the loop separate from the SWIGged objects and indexed the objects in the array with that. My manager agreed with me that this was quite a goofy solution and sent me down another path of figuring things out. Turns out, the problem was my lack of understanding how swig ties in with C++ and Python memory management. Either C++ or Python "owns" an object and if Python thinks it owns the object (It did because I created it in Python) and thinks it no longer has any references to the object(I wasn't using the C++ objects outside of that loop as far as Python knew because of threading crazyness), garbage collection will come by and trash the object, and eventually something else will use that chunk of memory (hence my crazy crashes and things showing up in odd places). There is a mention of object ownership and destruction for SWIGged objects in Python in the SWIG documentation, but I was new to all of this (I didn't even know what SWIG was or that I was using it at the start of the day!) so I ended up needing some pointers to the right place to look from someone that had seen this before. The solution: After creating the object in Python, just calling myObject.__disown()__. If things continue at this rate, I'll know more about Python by the end of this summer than I do about Perl (after spending 4 years teaching myself) and PHP (after spending 7+ years using it myself and 3+ years managing Gallery where we do things like beta test versions of PHP before they are released, use unit testing, and have paid security audits that I get to read.).

comments powered by Disqus