/* Makefile:
all: main main3
main: main.cpp
	g++ -o main main.cpp `python2-config --cflags --ldflags`
main3: main.cpp
	g++ -o main3 main.cpp `python3-config --cflags --ldflags` 
*/

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

//////////////////////////////////////////////////////////////////////////////////////////////
// Python2/Python3 compatibility layer (thanks to http://python3porting.com/cextensions.html)
#if PY_MAJOR_VERSION >= 3
  #define MOD_ERROR_VAL NULL
  #define MOD_SUCCESS_VAL(val) val
  #define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
  #define MOD_REGISTER(name) PyImport_AppendInittab(#name, PyInit_##name);
  #define MOD_DEF(name, doc, methods) \
          static struct PyModuleDef moduledef = { \
            PyModuleDef_HEAD_INIT, name, doc, -1, methods, }; \
          return PyModule_Create(&moduledef);
#else
  #define MOD_ERROR_VAL
  #define MOD_SUCCESS_VAL(val)
  #define MOD_REGISTER(name) PyImport_AppendInittab(#name, init##name);
  #define MOD_INIT(name) void init##name(void)
  #define MOD_DEF(name, doc, methods) \
          Py_InitModule3(name, methods, doc);
#endif
          
//////////////////////////////////////////////////////////////////////////////////////////////
        
static PyObject* sayHello( PyObject*, PyObject *args )
{
   std::cout << "Hello, World!" << std::endl;
   Py_RETURN_NONE;
}


// registration table
static PyMethodDef hello_methods[]={
    {"sayHello", sayHello, METH_NOARGS, "A simple example of an embedded function."},
    {NULL, NULL, 0, NULL}
};


MOD_INIT(hello)
{
    MOD_DEF("hello", "mod doc", hello_methods);
}

int main( )
{
   MOD_REGISTER(hello)

   Py_Initialize();

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