Ian Searle writes:
One of the programmers in my group first attempted this using the LLNL CXX package to develop the extension. This resulted in lots of trouble for us, which has yet to be resolved. Not because the CXX package isn't good. The problem may be that it is too good, or more precisely, uses C++ constructs that are too much for g++ (GCC-2.95.2). In this particular instance, g++ (Solaris) has a nasty bug that does not allow code built with it to catch exceptions. Instead, the exceptions get thrown all the way to the default exception handler which causes a core dump. We have absolutely no problems when we build the extension on Windows with VC++. Solaris, with g++ is another story altogether though.
I have also been unable to use GCC-2.95 for my other code projects, due to other apparent code gen bugs and miscelaneous other problems. GCC 2.95 is a landmark event--a reason for great excitement--but it isn't prime-time yet, I'm afraid.
So, as a means to explore alternatives, I wrote the C++ extension by hand. It turned out to fairly simple, and efficient (at least so far, I am only part way through my unit tests). To do this, I just developed a type extension for Python, almost exactly as described in the book: "Internet Programming with Python" (see the bstreammodule example). Adding a new type to Python gives you the opportunity to stash a pointer to your C++ object in the object structure. Important things to note:
Right, this is a very feasible approach. The goal of CXX is to make this as easy as declaring a derived object. But one can certainly do it oneself.
2) No global objects as we are linking against a C compiled Python.
There is a patch posted on the C++ SIG website, which modifies the configure script for Python to allow you to get your main linked with C++, which ensoures that global ctors get run correctly. If you use that, you don't need rule 2) above.
The C++ library the we wrote an extension for makes _heavy_ use of C++ STL containers.
Note that this is in potential contradiction with your rule 2) above. I'm sure you know that iostreams depends on global ctors, so your rule 2) means that cout is out. But also, some STL implementations make use of static global objects, and I don't see anything to imply that such an implementation is specifically nonconformant. So I would be worried that your current prescription is working due to fortuitous happenstance, depending on unspecified behavior of your current tool chain(s).
Getting select data out of the containers and into Python tuples, lists, and dictionaries is fairly simple. The hard part (assuming you are familiar with your own library) is learning the expectations of Python extensions. I found the book, and the standard Python documentation to be just fine.
CXX is also supposed to make this issue of ownership management trivial.
When we used the LLNL CXX extension, our contribution was about 500 lines of code. The "plain" extension is also about 500 lines of code. The main difference is in writing the plain extension I avoided use of C++ exceptions, and other C++ features that I know are not very portable (like new iostreams, but don't get me started...)
Frustrating, isn't it? I would add though, that its been more than 3 years since I have personally experienced a vendor C++ compiler whose exception mechanism didn't work. Outside of GCC, the rough points in C++ these days seem to lie in the areas of partial specialization, namespace resolution lookup rules, and associated arcana. GCC is generally conformant in almost all areas, but just has some issues with uneven implementation quality. Best regards, -- Geoffrey Furnish Actel Corporation furnish@actel.com Senior Staff Engineer 955 East Arques Ave voice: 408-522-7528 Placement & Routing Sunnyvale, CA 94086-4533 fax: 408-328-2303 "... because only those who write the code truly control the project." -- Jamie Zawinski