I found a more or less working solution using Python.h. I do not know how well it is, if anyone understands, correct, please.
The first file describes a wrapper class over a PyObject function or Python object.
cregister.cpp
#include <python3.4/Python.h> #include <stdlib.h> /***********************************************/ /* 1) code to route events to Python object */ /* note that we could run strings here instead */ /***********************************************/ class Caller{ private: PyObject* Route_Event(int count) { PyObject *args, *pres; /* call Python handler */ args = Py_BuildValue("(i)", count); /* make arg-list */ pres = PyEval_CallObject(Handler, args); /* apply: run a call */ return pres; } public: PyObject *Handler; /* keep Python object in C */ Caller() { Handler = NULL; /* keep Python object in C */ } /*****************************************************/ /* 2) python extension module to register handlers */ /* python imports this module to set handler objects */ /*****************************************************/ void setHandler(PyObject *arg) { /* save Python callable object */ Handler = arg; //Py_XDECREF(Handler); /* called before? */ //PyArg_Parse(arg, "(O)", &Handler); /* one argument */ //Py_XINCREF(Handler); /* add a reference */ } void triggerEvent(int arg) { /* let Python simulate event caught by C */ Route_Event(arg); } };
The second file is the swig interface:
cregister.i
%module cregister %{ #include "cregister.cpp" %} %include cregister.cpp
makefile to collect all this:
makefile
PYLIB = /usr/local/bin PYINC = /usr/include/python3.4 CMODS = _cregister.so CFLAGS = -O3 -fopenmp all: $(CMODS) cregister.py # обертка + действительный класс $(CMODS): cregister_wrap.o cregister.o g++ $(CFLAGS) -shared cregister_wrap.o cregister.o -L $(PYLIB) -o $@ # генерирует модуль обертки класса cregister_wrap.o: cregister_wrap.cxx g++ $(CFLAGS) cregister_wrap.cxx -c -g -fPIC -I $(PYINC) cregister_wrap.cxx: cregister.i swig -c++ -python cregister.i cregister.py: cregister.i swig -c++ -python cregister.i # программный код обертки класса C++ cregister.o: g++ $(CFLAGS) ../wavenet/cregister.cpp -c -g -fPIC -Wno-deprecated clean: rm -f *.pyc *.o *.so *.cxx cregister.py
Well and finally an illustration on Python3:
creg.py
#! /usr/bin/python3 """ ######################################################################### in Python, register for and handle event callbacks from the C language; compile and link the C code, and launch this with 'python3 creg.py'
################################################## ######################## "" "
#################################### # C calls these Python functions; # handle an event, return a result #################################### class Caller(object): def __init__(self, str): self.str=str def __call__(self, count): print(self.str.format(count)) ####################################### # Python calls a C extension module # to register handlers, trigger events ####################################### import sys sys.path.append('you_bin_path/') import cregister cal = Caller("Helllo{0}") cb = cregister.Caller() print('\nTest1:') cb.setHandler(cal) # register callback function for num in range(1, 10): res = cb.triggerEvent(num) # simulate events caught by C layer