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

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Harri Pesonen

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

    How do I pass the calling C++ class reference (or anything) to a callback?
    My code is:

    static PyObject*
    emb_Set(PyObjec t *self, PyObject *args)
    {
    char *key, *value;
    if(!PyArg_Parse Tuple(args, "ss", &key, &value))
    return NULL;
    // do something with the C++ class here
    // how the get the class instance pointer?
    Py_INCREF(Py_No ne);
    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_SimpleStr ing(script);
    Py_Finalize();

    Harri
  • T. Panbru

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

    Try encapsulating your C++ class reference in a CObject, using:

    PyObject* PyCObject_FromV oidPtr( void* cobj, void (*destr)(void *))
    void* PyCObject_AsVoi dPtr( PyObject* self)

    and so forth, to go back and forth between the C++ and Python realms.

    Check out the Python docs at:

    The official home of the Python Programming Language


    Tim
    [color=blue]
    > Harri Pesonen wrote:
    > How do I pass the calling C++ class reference (or anything) to a callback?
    > My code is:
    >
    > static PyObject*
    > emb_Set(PyObjec t *self, PyObject *args)
    > {
    > char *key, *value;
    > if(!PyArg_Parse Tuple(args, "ss", &key, &value))
    > return NULL;
    > // do something with the C++ class here
    > // how the get the class instance pointer?
    > Py_INCREF(Py_No ne);
    > 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_SimpleStr ing(script);
    > Py_Finalize();
    >
    > Harri[/color]

    Comment

    • David Abrahams

      #3
      Re: Simple question: How to pass a C++ class reference to acallback?

      "T. Panbru" <panbru@comcast .net> writes:
      [color=blue]
      > Try encapsulating your C++ class reference in a CObject, using:
      >
      > PyObject* PyCObject_FromV oidPtr( void* cobj, void (*destr)(void *))
      > void* PyCObject_AsVoi dPtr( 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
      >[/color]

      Or use one of the high-level wrapping tools such as Boost.Python
      (http://www.boost.org/libs/python) which make this stuff much easier
      and safer.

      --
      Dave Abrahams
      Boost Consulting

      Comment

      • Harri Pesonen

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

        David Abrahams wrote:[color=blue]
        > "T. Panbru" <panbru@comcast .net> writes:
        >[color=green]
        >>Try encapsulating your C++ class reference in a CObject, using:
        >>
        >> PyObject* PyCObject_FromV oidPtr( void* cobj, void (*destr)(void *))
        >> void* PyCObject_AsVoi dPtr( 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
        >>[/color]
        >
        >
        > Or use one of the high-level wrapping tools such as Boost.Python
        > (http://www.boost.org/libs/python) which make this stuff much easier
        > and safer.[/color]

        Boost.Python is not 2.3 compatible yet, but it seems very good.

        Harri

        Comment

        • Harri Pesonen

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

          I read it twice, but I'm not sure that I got it.

          You mean that I add something like:

          static PyObject*
          emb_Set(PyObjec t *self, PyObject *args) {
          char *key, *value;
          if(!PyArg_Parse Tuple(args, "ss", &key, &value))
          return NULL;
          // how the get the class instance pointer:
          PyObject *c_api_object = PyObject_GetAtt rString(self, "_C_API");
          if (c_api_object) {
          if (PyCObject_Chec k(c_api_object) ) {
          myClass *p = (myClass *)PyCObject_AsV oidPtr(c_api_ob ject);

          // do something with the C++ class here
          }
          Py_DECREF(c_api _object);
          }
          Py_INCREF(Py_No ne);
          return Py_None;
          }

          And in C++ class:

          Py_Initialize() ;
          PyObject *m = Py_InitModule(" test", EmbMethods);
          // ??
          PyObject *c_api_object = PyCObject_FromV oidPtr((void *)this, NULL);
          if (c_api_object) {
          PyModule_AddObj ect(m, "_C_API", c_api_object);
          PyRun_SimpleStr ing(script);
          }
          Py_Finalize();



          T. Panbru wrote:
          [color=blue]
          > Try encapsulating your C++ class reference in a CObject, using:
          >
          > PyObject* PyCObject_FromV oidPtr( void* cobj, void (*destr)(void *))
          > void* PyCObject_AsVoi dPtr( 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
          >[color=green]
          > > Harri Pesonen wrote:[/color]
          >[color=green]
          >> How do I pass the calling C++ class reference (or anything) to a
          >> callback?
          >> My code is:
          >>
          >> static PyObject*
          >> emb_Set(PyObjec t *self, PyObject *args)
          >> {
          >> char *key, *value;
          >> if(!PyArg_Parse Tuple(args, "ss", &key, &value))
          >> return NULL;
          >> // do something with the C++ class here
          >> // how the get the class instance pointer?
          >> Py_INCREF(Py_No ne);
          >> 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_SimpleStr ing(script);
          >> Py_Finalize();
          >>
          >> Harri[/color]
          >
          >[/color]

          Comment

          • Harri Pesonen

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

            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(PyObjec t *self, PyObject *args) {
            char *key, *value;
            if(!PyArg_Parse Tuple(args, "ss", &key, &value))
            return NULL;
            // how the get the class instance pointer:
            PyObject *m = PyImport_Import Module("test");
            if (m) {
            PyObject *c_api_object = PyObject_GetAtt rString(m, "_C_API");
            if (c_api_object) {
            myClass *p = (myClass *)PyCObject_AsV oidPtr(c_api_ob ject);
            // do something with the C++ class here
            Py_DECREF(c_api _object);
            }
            Py_DECREF(m);
            }
            Py_INCREF(Py_No ne);
            return Py_None;
            }

            Harri Pesonen <fuerte@sci.f i> wrote in message news:<lj45b.229 8$ZB4.1613@read er1.news.jippii .net>...[color=blue]
            > I read it twice, but I'm not sure that I got it.
            >
            > You mean that I add something like:
            >
            > static PyObject*
            > emb_Set(PyObjec t *self, PyObject *args) {
            > char *key, *value;
            > if(!PyArg_Parse Tuple(args, "ss", &key, &value))
            > return NULL;
            > // how the get the class instance pointer:
            > PyObject *c_api_object = PyObject_GetAtt rString(self, "_C_API");
            > if (c_api_object) {
            > if (PyCObject_Chec k(c_api_object) ) {
            > myClass *p = (myClass *)PyCObject_AsV oidPtr(c_api_ob ject);
            >
            > // do something with the C++ class here
            > }
            > Py_DECREF(c_api _object);
            > }
            > Py_INCREF(Py_No ne);
            > return Py_None;
            > }
            >
            > And in C++ class:
            >
            > Py_Initialize() ;
            > PyObject *m = Py_InitModule(" test", EmbMethods);
            > // ??
            > PyObject *c_api_object = PyCObject_FromV oidPtr((void *)this, NULL);
            > if (c_api_object) {
            > PyModule_AddObj ect(m, "_C_API", c_api_object);
            > PyRun_SimpleStr ing(script);
            > }
            > Py_Finalize();
            >
            >
            >
            > T. Panbru wrote:
            >[color=green]
            > > Try encapsulating your C++ class reference in a CObject, using:
            > >
            > > PyObject* PyCObject_FromV oidPtr( void* cobj, void (*destr)(void *))
            > > void* PyCObject_AsVoi dPtr( 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
            > >[color=darkred]
            > > > Harri Pesonen wrote:[/color][/color]
            >[color=green][color=darkred]
            > >> How do I pass the calling C++ class reference (or anything) to a
            > >> callback?
            > >> My code is:
            > >>
            > >> static PyObject*
            > >> emb_Set(PyObjec t *self, PyObject *args)
            > >> {
            > >> char *key, *value;
            > >> if(!PyArg_Parse Tuple(args, "ss", &key, &value))
            > >> return NULL;
            > >> // do something with the C++ class here
            > >> // how the get the class instance pointer?
            > >> Py_INCREF(Py_No ne);
            > >> 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_SimpleStr ing(script);
            > >> Py_Finalize();
            > >>
            > >> Harri[/color]
            > >
            > >[/color][/color]

            Comment

            • David Abrahams

              #7
              Re: Simple question: How to pass a C++ class reference to acallback?

              Harri Pesonen <fuerte@sci.f i> writes:
              [color=blue]
              > David Abrahams wrote:[color=green]
              >> "T. Panbru" <panbru@comcast .net> writes:
              >>[color=darkred]
              >>>Try encapsulating your C++ class reference in a CObject, using:
              >>>
              >>> PyObject* PyCObject_FromV oidPtr( void* cobj, void (*destr)(void *))
              >>> void* PyCObject_AsVoi dPtr( 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
              >>>[/color]
              >> Or use one of the high-level wrapping tools such as Boost.Python
              >> (http://www.boost.org/libs/python) which make this stuff much easier
              >> and safer.[/color]
              >
              > Boost.Python is not 2.3 compatible yet, but it seems very good.[/color]

              The CVS version is 2.3 compatible; you can download a snapshot from
              http://www.boost-consulting.com/boost.tar.bz2 or you can access our
              anonymous CVS or a mirror (about a day behind).

              --
              Dave Abrahams
              Boost Consulting

              Comment

              Working...