Boost Python is pretty awesome. It’s a way to wire up your C++ code to Python without having to go all the way into the fairly low level Python C API. I have been working on a C++ application using Qt, and I wanted to embed Python in the app to allow user scripting. There’s a lot I could write about that, but I’m lazy, so maybe some of the subtleties of allowing users to script your app will wind up in another post.
I looked at a few alternatives to Boost before I settled on it. Since I am working on a Qt app, I looked at PyQt and PySide and how they do things first. Both of them are bindings for the whole Qt framework with a bunch of UI and miscellaneous stuff, but also have systems for wrapping that stuff which you can use for your own code and classes. Exposing Qt to my users would have been pretty neat, so they could build their own UI’s, or talk to databases or network services with the Qt classes pretty much “for free.” PyQt licensing is a bit tricky, and I’m not certain if my app will eventually be a commercial product, so I didn’t want to deal with the complexities. On a personal project like this one, sometimes laziness is the best way forward. That said, it works well, and the license cost is not at all unreasonable. If I had a boss on this project who handed me PyQt as the way forward, I probably would have been able to make it work. PySide is similar to PyQt. Instead of being managed by a third party like PyQt, PySide is developed in-house by the maintainers of Qt,
Nokia erm I mean Digia. Nope, I think it’s the Qt Company for the moment. That said, I need Qt 5.4 support, and PySide seems to have gotten of given up at Qt 4.x. There may be some work maintaining it someplace that I am not looking, but the official release doesn’t seem to be very current. They also don’t support Python 3, which I want to support going forward. My current build is done with Python 2.7, but I’d rather support it from the get-go than have a big panic when I decide I can’t possibly live without the latest greatest python next month. Shiboken, the wrapper generator used with PySide is also terribly documented. In theory it supports doing your own stuff without involving PySide, but finding a simple guide to doing it was frustrating, and I had no idea what I was doing.
I tried SWIG, but it hates namespaces. Dealing with it in a real live modern-ish C++ code base proved to be really annoying. I could wrap simple classes, but wrapping QObject derived classes spread across multiple modules in different namespaces using SWIG proved to be remarkably similar to bashing my face against the mouth of an angry lion. It’s not that it can’t be done, but you’ll frequently find your face being ripped off if you do. Also, SWIG is very much targeted toward making Python modules, rather than embedding python. While I did make simple Python modules in my experiments, I never did manage to get it embedded in my app properly.
Which brings me to Boost Python. It builds as a part of my existing code, so it works fine with whatever my real app is. On the other hand, while SWIG and Shiboken are generators for the binding, Boost requires me to actively expose stuff by hand. I would have much preferred to have my Python bindings ‘just work’ which is basically impossible with Boost. In an ideal world, I’d just write doxygen comments in my header files, run a generator, and magically have a fully documented, working Python API for my app. Oh well. Programming sucks, and you have to do work to make the program that you want. I’ll dig more into the nitty gritty of using Boost.Python in my next post, now that I have established the rationale for using it that led me down that path.
2 thoughts on “Embedding Python in my App Part I An Unexpected Journey”
Pingback: Embedding Python in my App Part II The Desolation of Documentation | Will Rosecrans Blog
Pingback: Adventures in Userland I – Brown Paper Packages Tied Up in std::string, xz, ar, tar, gz, and spaghetti | Will Rosecrans Blog