Alex Rivera | Logout

C++ with Python embedding: crash if Python not installed

Asked 2009-09-07T06:56:51.613
23

I'm developing on Windows, and I've searched everywhere without finding anyone talking about this kind of thing.

I made a C++ app on my desktop that embedded Python 3.1 using MSVC. I linked python31.lib and included python31.dll in the app's run folder alongside the executable. It works great. My extension and embedding code definitely works and there are no crashes.

I sent the run folder to my friend who doesn't have Python installed, and the app crashes for him during the scripting setup phase.

A few hours ago, I tried the app on my laptop that has Python 2.6 installed. I got the same crash behavior as my friend, and through debugging found that it was the Py_Initialize() call that fails.

I installed Python 3.1 on my laptop without changing the app code. I ran it and it runs perfectly. I uninstalled Python 3.1 and the app crashes again. I put in code in my app to dynamically link from the local python31.dll, to ensure that it was using it, but I still get the crash.

I don't know if the interpreter needs more than the DLL to start up or what. I haven't been able to find any resources on this. The Python documentation and other guides do not seem to ever address how to distribute your C/C++ applications that use Python embedding without having the users install Python locally. I know it's more of an issue on Windows than on Unix, but I've seen a number of Windows C/C++ applications that embed Python locally and I'm not sure how they do it.

What else do I need other than the DLL? Why does it work when I install Python and then stop working when I uninstall it? It sounds like it should be so trivial; maybe that's why nobody really talks about it. Nevertheless, I can't really explain how to deal with this crash issue.

Thank you very much in advance.

Edit
Report

1 Answer

13

Nice. And if you do not want to zip, copy Python26\DLLs & Python26\lib to your exe directory as:

.\myexe.exe       
.\python26.dll
.\Python26\DLLs
.\Python26\lib

And then set PYTHONHOME with Py_SetPythonHome() API. Apparently, this API is not in the list of "allowed" calls before Py_Initialize();

Below worked for me on Windows (Python not installed):

#include "stdafx.h"
#include <iostream>
#include "Python.h"

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
   char pySearchPath[] = "Python26";
   Py_SetPythonHome(pySearchPath);
   Py_Initialize();
   PyRun_SimpleString("from time import time,ctime\n"
                     "print 'Today is',ctime(time())\n");
   //cerr << Py_GetPath() << endl;
   Py_Finalize();

    return 0;
}

Good that the search path is relative w.r.t the exe. Py_GetPath can show you where all it is looking for the modules.

answered 2010-06-03T23:02:34.060

Your Answer