Embedding Python in Your C Programs
Python data structures are returned from and passed to the Python interpreter in the form of PyObjects. To get to a specific type, you need to perform a cast to the correct type. For instance, you can get to a PyIntObject pointer by casting a PyObject pointer. If you don't know for sure what the variable's type is, though, blindly performing a cast could have disastrous results. In such a case, you can call one of the many Check() functions to see if an object is indeed of an appropriate type, such as the PyFloat_Check() function that returns true if the object could indeed be cast to a float. In other words, it returns true if the object is a float or a subtype of a float. If you'd rather know whether the object is exactly a float, not a subclass, you can use PyFloat_CheckExact().
The opaque PyObject structure isn't actually useful to a C program though. In order to access Python data in your program, you'll need to use a variety of conversion functions that will return a native C type. For example, if you want to convert a PyObject to a long int, you can run PyInt_AsLong(). PyInt_AsLong is a safe function, and will perform a checked casting to PyIntObject before extracting the long int value. If you know for sure that the value you're converting is indeed an int, it may be wasteful to perform the extra checking—especially if it's inside of a tight loop.
Often, Python functions ask for or return Python sequence objects, such as tuples or lists. These objects don't have directly corresponding types in C, but Python provides functions that allow you to build them from C data types. As an example, let's take a look at building a tuple since you'll need to be able to do that to call a function using PyObject_CallObject().
The first step to creating a new tuple is to construct an empty tuple with PyTuple_New(), which takes the length of the tuple and returns a PyObject pointer to a new tuple. You can then use PyTuple_SetItem to set the values of the tuple items, passing each value as a PyObject pointer.
You should now have enough to get started with embedding Python scripts inside your own applications. For more information, take a look at the Python documentation. “Extending and Embedding the Python Interpreter” goes into more detail on going the other direction and embedding C functions inside Python. The “Python/C API Reference Manual” also has detailed reference documentation on all of the functions available for embedding Python in your program. The Linux Journal archives also contain an excellent article from Ivan Pulleyn that discusses issues for multithreaded programs that embed Python.
Resources for this article: /article/8714.
William Nagel is the Chief Software Engineer for Stage Logic, LLC, a small software development company, where he develops real-time systems based on Linux. He is also the author of “Subversion Version Control: Using the Subversion Version Control System in Development Projects”.
- VMware's Clarity Design System
- Let's Go to Mars with Martian Lander
- Applied Expert Systems, Inc.'s CleverView for TCP/IP on Linux
- Papa's Got a Brand New NAS
- My Childhood in a Cigar Box
- Rogue Wave Software's TotalView for HPC and CodeDynamics
- Panther MPC, Inc.'s Panther Alpha
- Jetico's BestCrypt Container Encryption for Linux
- Simplenote, Simply Awesome!
- Custom checks and notifications for Nagios