Embedding Python into a VC6 app?

paul at fxtech.com paul at fxtech.com
Sat Feb 17 11:45:30 EST 2001


--- In python-list at y..., ransen_spam_me_not at n... (Owen F. Ransen) 
wrote:
> Is there somewhere around a step by step guide to
> embedding Python into a VC6 Windows application?

Not really any step-by-step ones that I have seen. I am in the 
process of doing this myself, so was thinking of starting a "HOWTO" 
for Python embedding. I am sure people would find this interesting, 
and I'd love to have people contribute ideas.

To kick it off, this is what I did:

1. Obviously - download and install Python.
I did this with Python 2.0, but there was not a debug .lib included, 
so I got the latest CVS and built my own 2.1 DLL and LIB, then 
downloaded and installed the 2.1 alpha release.

2. Add a file to your project to isolate your Python stuff. Set an 
include path on it to include the Python headers directory.

3. In your file, do this:
#include <Python.h>

If the file compiles and your app links, you have set your headers up 
correctly. Also note that on Windows including Python.h will 
automatically add the appropriate link library for you (Python21_d.lib 
or Python21.lib, depending on the debug mode).

4. Add some code to initialize the Python interpreter, then register 
your app's extension functions. One of things you will want to do is 
redirect prints from within scripts (to stdout and stderr) to your own 
functions, so you can display the output in a window. Here is how I 
did it:

void InitPython()
{
    ::Py_SetProgramName("YOUR PROGRAM NAME");
    ::Py_Initialize();

    ::Py_InitModule("mymodule", my_methods);

    ::PyRun_SimpleString(
        "import mymodule\n"
        "class my_stdout:\n"
        "    def write(self, string):\n"
        "        mymodule.stdout(string)\n"
        "\n"
        "class my_stderr:\n"
        "    def write(self, string):\n"
        "        mymodule.stderr(string)\n"
        "\n"
        "import sys\n"
        "sys.stdout = my_stdout()\n"
        "sys.stderr = my_stderr()\n"
        "sys.path.append(PATH TO YOUR SCRIPTS)\n"
        "\n"
    );
}

static PyObject *s_stdout(PyObject *self, PyObject *args)
{
    char *string;
    if (!PyArg_ParseTuple(args, "s", &string))
        return NULL;

    // DO SOMETHING WITH THE STRING!
    // NOTE - Python new-lines only have a '\n' - you will need
    // to convert to "\r\n" on Windows

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *s_stderr(PyObject *self, PyObject *args)
{
    char *string;
    if (!PyArg_ParseTuple(args, "s", &string))
        return NULL;

    // DO SOMETHING WITH THE STRING!

    Py_INCREF(Py_None);
    return Py_None;
}

struct PyMethodDef my_methods[] = 
{
    { "stdout",	s_stdout, METH_VARARGS },
    { "stderr",	s_stderr, METH_VARARGS },
    { NULL,	NULL }
};

When you are all done, call ::Py_Finalize().
Now you can call the other script functions to run your own scripts 
(or lines of code). 

You might want to check out http://www.mcmillan-inc.com/embed.html for 
some ideas.

I hope this helps get you started.






More information about the Python-list mailing list