Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Simple question: How to pass a C++ class reference to a callback?

Reply
Thread Tools

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

 
 
Harri Pesonen
Guest
Posts: n/a
 
      09-02-2003
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
 
Reply With Quote
 
 
 
 
T. Panbru
Guest
Posts: n/a
 
      09-02-2003
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


 
Reply With Quote
 
 
 
 
David Abrahams
Guest
Posts: n/a
 
      09-02-2003
"T. Panbru" <(E-Mail Removed)> writes:

> 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
>


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
www.boost-consulting.com
 
Reply With Quote
 
Harri Pesonen
Guest
Posts: n/a
 
      09-02-2003
David Abrahams wrote:
> "T. Panbru" <(E-Mail Removed)> writes:
>
>>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
>>

>
>
> 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.


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

Harri

 
Reply With Quote
 
Harri Pesonen
Guest
Posts: n/a
 
      09-02-2003
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

>
>


 
Reply With Quote
 
Harri Pesonen
Guest
Posts: n/a
 
      09-03-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 <(E-Mail Removed)> wrote in message news:<lj45b.2298$(E-Mail Removed)> ...
> 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

> >
> >

 
Reply With Quote
 
David Abrahams
Guest
Posts: n/a
 
      09-03-2003
Harri Pesonen <(E-Mail Removed)> writes:

> David Abrahams wrote:
>> "T. Panbru" <(E-Mail Removed)> writes:
>>
>>>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
>>>

>> 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.

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


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
www.boost-consulting.com
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
difference between pass by address and pass by reference!! blufox C Programming 2 04-03-2006 02:53 PM
Pass by reference / pass by value Jerry Java 20 09-09-2005 06:08 PM
Pass by Pointer * or Pass by Reference &? Robert C++ 10 08-24-2005 04:15 PM
Pass-by-reference instead of pass-by-pointer = a bad idea? Mr A C++ 111 07-14-2005 03:04 AM



Advertisments