Tags

,

Recently I had need to embed Python 3 into an existing C++ code base, and along the way I realized that I needed to embed a simple Python module into my code. After spending way too much time surfing the Web, reading documentation, and attempting to find an example, I finally figured things out.

The code below is a distillation of my efforts.

In particular Python bug 4592 was helpful. It pointed the way toward using PyImport_AppendInittab. 

My example is also inspired in part from the code here, but as you will see the link does not use PyImport_AppendInittab (a key missing ingriedient), and it also attempts to support Python 2.x.

We create a module named “hello” with a single method “sayHello” and invoke the interpreter on it.

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

static PyObject* sayHello( PyObject*, PyObject *args )
{
   std::cout << "Hello, World!" << std::endl;
   Py_RETURN_NONE;
}

static PyMethodDef HELLO_METHODS[] =
{
   {"sayHello", sayHello, METH_NOARGS, "A simple example of an embedded function."},
   NULL
};

static struct PyModuleDef HELLO_MODULE = {
   PyModuleDef_HEAD_INIT,
   "hello",
   NULL,
   -1,
   HELLO_METHODS,
   NULL, NULL, NULL, NULL
};

PyMODINIT_FUNC
PyInit_hello_module(void)
{
   std::cout << "Initializaing module!" << std::endl;
   PyObject* m = PyModule_Create(&HELLO_MODULE);
   if ( ! m )
   {
      std::cerr << "Failed to create module..." << std::endl;
      return NULL;
   }
   return m;
}

int main( )
{
   Py_Initialize();
   PyImport_AppendInittab("hello", PyInit_hello_module);

   PyRun_SimpleString("import hello; print( dir(hello) ); hello.sayHello()\n");
   Py_Finalize();
   return 0;
}
Advertisements