Awasu » Embedding Python: Adding the Python interpreter to your program
Sunday 30th November 2014 7:55 AM []

Let's set up a simple C++ application that embeds our newly-built version of Python.

We'll get it to run the test script from the previous tutorial, but from our C++ app instead of from the command line.

#include <fstream>
#include <cassert>
  
#include "python.h"
  
void
main( int argc , char** argv )
{
    // initialize Python
    Py_Initialize() ;
  
    // open the script
    const char* pFilename = argv[1] ; // nb: first command-line argument
    FILE* fp ;
    errno_t rc = fopen_s( &fp , pFilename , "r" ) ;
    assert( rc == 0 && fp != NULL ) ;
  
    // run the script
    int rc2 = PyRun_SimpleFile( fp , pFilename ) ;
    assert( rc2 == 0 ) ;
  
    // clean up
    fclose( fp ) ;
    Py_Finalize() ;
}

Note that we are just using assert's for error-checking, which means that if something goes wrong, release builds will just keep ploughing on, and probably crash soon after. We talk about how to check for errors properly here.

We simply open the file we want to run, pass the file handle into PyRun_SimpleFile()[1]The second parameter to PyRun_SimpleFile() is simply used for reporting errors. You can pass in any value here, and it will be shown when Python reports the error., where Python will read and execute the file contents.

If we try to compile this program, we get a compile error because the compiler doesn't know where to find python.h, so let's fix that (see right).

The file now compiles, but we then get a link error. Since we #include "python.h", the DLL will be implicitly loaded, but we need to tell the linker where to find the import library (see right).

The program now compiles and links, but when we try to run it, Windows complains about a missing DLL.

This is happening because we are implicitly loading the Python DLL, which means that the DLL needs to be somewhere in the DLL search path. The safest, most reliable way to do this is to put a copy of the DLL in the same directory as your EXE[2]Remember to use the debug build of the DLL (python27_d.dll) with the debug build of your program, and the release build (python27.dll) with your release build.[3]Alternatively, you can add the directory containing these DLL's to your path..

Now, when we run our program, Python seems to start, but it complains about not being able to find a module called site.

This happens because when Python starts, it tries to import a module called site, which contains a bunch of initialization code. It can't find it, and so aborts with this error.

The site module is part of the standard Python library and for now, we'll tell Python how to find it by setting the PYTHONPATH environment variable[4]We'll revisit this subject later. to the Lib/ sub-directory of wherever you unpacked the Python source code files.

At last, everything works! Our C++ program successfully loads Python and runs our script.

Download the source code here.


   [ + ]

1. The second parameter to PyRun_SimpleFile() is simply used for reporting errors. You can pass in any value here, and it will be shown when Python reports the error.
2. Remember to use the debug build of the DLL (python27_d.dll) with the debug build of your program, and the release build (python27.dll) with your release build.
3. Alternatively, you can add the directory containing these DLL's to your path.
4. We'll revisit this subject later.
Have your say