Click here to Skip to main content
15,860,972 members
Articles / Desktop Programming / MFC

Embedding Python In Your C++ Application

Rate me:
Please Sign up or sign in to vote.
4.58/5 (19 votes)
22 May 2006BSD4 min read 107.4K   2.7K   72   13
Wrapper classes to embed the Python interpreter in Standard C++ code

Introduction

You have a problem.
You wrote a cross-platform mail server in C++.
It runs on Windows, Linux and Mac.

Well, is that a problem?
No, it's cool.

But now, you feel pathetic about yourself.
Your manager says, "all is fine, but I want the users to edit the config file using a GUI."

Yes, just a single dialog box, with a few input fields.
But how to add it to your command line application?

"Qt?"

"No, we can't spend big cash for just a single window."

"Gtk? or wxWidgets?"

"No, we can't add that much bloat to our executable."
"And mind it, I need it fast, 1 day, at-most".

Now you feel stuck.
It's itching your sole and steaming your brow.

I tell you, stay cool - read on.

Embed Python

Yes, that is the answer to your woes, embed Python.
Python comes bundled with Tkinter - the lightweight, mature, cross-platform UI toolkit.

You can handcraft your UI in a matter of few minutes. And it won't add much to the size of your application.

I will show you how easy it is.

"But one word before that, why Python?"
Well, these are some of the reasons that I personally like it:

  1. It is straightforward. You can write useful stuff just after playing around with the language for a few minutes.
  2. The syntax forces the lazy programmer to write clean, well indented code. Still it does not force a particular programming style on you.
  3. Though interpreted, performance is commendable.
  4. You can extend and embed it.

Many smart people are using it in demanding systems. Some of the most celebrated Python users include:

  1. Google
  2. NASA
  3. Industrial Light and Magic (Yes, StarWars owes much to Python !)

"Ok, Ok. I agree that, on its own, Python is a good language."
"But I have had enough, trying to embed it."
"The C API is very low-level, and it never worked as documented."

Yes, I agree that the documentation on embedding Python is missing something. But remember what I said, 'I will show you an easy way.'

I have written a C++ wrapper over the Python API. Just use it.

You no longer need to worry about mapping Python objects to C/C++ types. You don't need to reference count objects on heap, for garbage collection.

All is taken care of. Just use it.

Using the Code

The classes that we are going to use are declared in 'pyembed.h'.

Consider the following Python script:

Listing 1 - test.py

C++
def multiply(a,b):
    "Finds a product, the other way round!"
    c = 0
    for i in range(0, a):
     c = c + b
    return c

The function "multiply" takes two integers as arguments and returns an integer. Let us write some code to call this function from C++.

Listing 2 - test_pyembed.cpp

C++
#include <iostream>
#include "pyembed.h"
using namespace pyembed; // for brevity

int
main(int argc, char** argv)
{
  try // always check for Python_exceptions
    {

      // Create an instance of the interpreter.
      Python py(argc, argv);

      // Load the test module into the interpreter
      py.load("test");           

      // value returned by python is stored here    
      long ret = 0; 

      // our argument list that maps string values 
      // to their python types    
      Arg_map args; 

      // fill up argument strings and their types.
      args["10"] = Py_long;
      args["20"] = Py_long;

      // make the call
      py.call("multiply", args, ret);

      // will print 200
      std::cout << ret << '\n'; 

      return 0;
    }
  catch (Python_exception ex)
    {
      std::cout << ex.what();
    }
  return 0;
}

I am not going to explain the code, as it is well commented. Our main actor here is the class "Python". It has a large variety of "call" functions, that can be used to call Python functions that return different kind of objects. The following Python types are handled as return values and mapped to C++ types:

Python returnMapped to
PyStringstd::string
PyLong/PyIntlong
PyFloatdouble
PyTuplestd::vector<std::string> (typedefed as String_list)
PyListstd::vector<std::string> (typedefed as String_list)
PyDictstd::map<std::string, std::string> (typedefed as String_map)

Tuples, lists and dictionaries embedded inside other objects are returned as comma or colon delimited strings, which you further need to parse. But such values are seldom required.

You can pass the following C++ types as arguments to Python functions:

long(Py_long)
double(Py_real)
std::string or char(Py_string)

You can also execute arbitrary Python scripts using the "run_string" function.
To execute a script file as it is, use the "run_file" function.

Example:

py.run_string("print 'Hello World from Python!');

py.run_file("test.py");

Just go through pyembed.h to get a feel of all the facilities offered by our "Python" class.

The downloadable zip file contains the code of the pyembed library, along with a small C++ commandline program that demonstrates a GUI using Tkinter.

Compiling

Here is the command I used on Linux to compile the sample application "users.cpp":

g++ -o users -I/usr/local/include/python2.4 pyembed.cpp 
	users.cpp -L/usr/local/lib/python2.4/config -Xlinker 
	-export-dynamic -lpython2.4 -lm -lpthread -ltk -lutil

You need to change the -I and -L options to point to your Python installation folders.

For compiling on Windows (or any other platform), download and install Python and link the application with the platform specific Python library. If you are using Visual C++, you may also need to link with the multi-threaded runtime library. I don't work on Windows, so this is just an imagination. Always remember to add pyembed.cpp and pyembed.h to your project.

Play around with the sample code. Make changes to "adduserform.py" while the application is still running, and see if the changes are reflected immediately. Yes, you can modify the UI, without recompiling the program. You can modify it on-the-fly. This is just one of the advantages of giving your application a Python face.

The py_embed library is not yet complete. But still it can be put to many useful purposes. Please send me your comments, suggestions and bug reports. Thank you for staying this long. Bye.

History

  • 23rd May, 2006: Initial post

License

This article, along with any associated source code and files, is licensed under The BSD License


Written By
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionHow to fix The application was unable to start correctly (0xc000007b). Click OK to close the application. Pin
Member 133207872-Oct-17 22:49
Member 133207872-Oct-17 22:49 
QuestionWhere's the source code Pin
billthu215-Mar-14 19:54
billthu215-Mar-14 19:54 
QuestionBuild errors - Visual Studio 2005 Pin
rmp25127-Oct-12 14:48
rmp25127-Oct-12 14:48 
QuestionCall Python program from C++ Pin
BenPen9513-Jul-11 4:28
BenPen9513-Jul-11 4:28 
Generalsequence of the arguments Pin
Oka Kurniawan21-Sep-10 0:11
Oka Kurniawan21-Sep-10 0:11 
GeneralProblem with "RE" module Pin
tito20718-Jun-08 21:10
tito20718-Jun-08 21:10 
First of all, congratulations for your job.

I have a problem because, every time I use the module "RE" (regular expressions), the application crashes with a segmentation fault. Only by adding the sentence "import re" on the script file, the application fails.
I don't have this problem working with any other module I've tried, neither with my custom modules.

The error only occurs when I run the script by loading the module (function load), never when I try to run the entire script with the function run_file

I'm working on Linux, GCC 4.3.1 and Python 2.5.

Thanks in advance.
GeneralWindows Pin
ALEXNG8823-Jul-07 21:43
ALEXNG8823-Jul-07 21:43 
GeneralRe: Windows Pin
AnOldGreenHorn24-Jul-07 1:01
AnOldGreenHorn24-Jul-07 1:01 
Questioncan you help me? [modified] Pin
yzslhawk8-Jul-06 22:52
yzslhawk8-Jul-06 22:52 
AnswerRe: can you help me? [modified] Pin
AnOldGreenHorn9-Jul-06 18:29
AnOldGreenHorn9-Jul-06 18:29 
GeneralRe: can you help me? Pin
yzslhawk12-Jul-06 3:45
yzslhawk12-Jul-06 3:45 
GeneralRe: can you help me? Pin
yzslhawk12-Jul-06 4:14
yzslhawk12-Jul-06 4:14 
GeneralArticles on the same topic... Pin
Jun Du23-May-06 4:16
Jun Du23-May-06 4:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.