Simple question: How to pass a C++ class reference to a callback?

Harri Pesonen Harri.Pesonen at wicom.com
Wed Sep 3 10:14:22 CEST 2003


I was close, but it appears that self is always NULL in embedded function (why?).

So the correct embedded function is

static PyObject*
emb_Set(PyObject *self, PyObject *args) {
    char *key, *value;
    if(!PyArg_ParseTuple(args, "ss", &key, &value))
        return NULL;
    // how the get the class instance pointer:
    PyObject *m = PyImport_ImportModule("test");
    if (m) {
        PyObject *c_api_object = PyObject_GetAttrString(m, "_C_API");
        if (c_api_object) {
            myClass *p = (myClass *)PyCObject_AsVoidPtr(c_api_object); 
            // do something with the C++ class here
            Py_DECREF(c_api_object);
        }
        Py_DECREF(m);
    }
    Py_INCREF(Py_None);
    return Py_None;
}

Harri Pesonen <fuerte at sci.fi> wrote in message news:<lj45b.2298$ZB4.1613 at reader1.news.jippii.net>...
> I read it twice, but I'm not sure that I got it.
> 
> You mean that I add something like:
> 
> static PyObject*
> emb_Set(PyObject *self, PyObject *args) {
>      char *key, *value;
>      if(!PyArg_ParseTuple(args, "ss", &key, &value))
>          return NULL;
>      // how the get the class instance pointer:
>      PyObject *c_api_object = PyObject_GetAttrString(self, "_C_API");
>      if (c_api_object) {
>          if (PyCObject_Check(c_api_object)) {
>              myClass *p = (myClass *)PyCObject_AsVoidPtr(c_api_object); 
> 
>              // do something with the C++ class here
>          }
>          Py_DECREF(c_api_object);
>      }
>      Py_INCREF(Py_None);
>      return Py_None;
> }
> 
> And in C++ class:
> 
>      Py_Initialize();
>      PyObject *m = Py_InitModule("test", EmbMethods);
>      // ??
>      PyObject *c_api_object = PyCObject_FromVoidPtr((void *)this, NULL);
>      if (c_api_object) {
>          PyModule_AddObject(m, "_C_API", c_api_object);
>          PyRun_SimpleString(script);
>      }
>      Py_Finalize();
> 
> 
> 
> T. Panbru wrote:
> 
> > Try encapsulating your C++ class reference in a CObject, using:
> > 
> >     PyObject* PyCObject_FromVoidPtr( void* cobj, void (*destr)(void *))
> >     void* PyCObject_AsVoidPtr( PyObject* self)
> > 
> > and so forth, to go back and forth between the C++ and Python realms.
> > 
> > Check out the Python docs at:
> > 
> >     http://www.python.org/doc/2.3/api/cObjects.html
> > 
> > Tim
> > 
> >  > Harri Pesonen wrote:
>  
> >> How do I pass the calling C++ class reference (or anything) to a 
> >> callback?
> >> My code is:
> >>
> >> static PyObject*
> >> emb_Set(PyObject *self, PyObject *args)
> >> {
> >>     char *key, *value;
> >>     if(!PyArg_ParseTuple(args, "ss", &key, &value))
> >>         return NULL;
> >>     // do something with the C++ class here
> >>     // how the get the class instance pointer?
> >>     Py_INCREF(Py_None);
> >>     return Py_None;
> >> }
> >>
> >> static PyMethodDef EmbMethods[] = {
> >>     {"Set", emb_Set, METH_VARARGS, "Sets the given variable."},
> >>     {NULL, NULL, 0, NULL}
> >> };
> >>
> >> in C++ class:
> >>
> >>     Py_Initialize();
> >>     Py_InitModule("test", EmbMethods);
> >>     PyRun_SimpleString(script);
> >>     Py_Finalize();
> >>
> >> Harri
> > 
> >




More information about the Python-list mailing list