473,329 Members | 1,307 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,329 software developers and data experts.

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(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
Jul 18 '05 #1
6 6614
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


Jul 18 '05 #2
"T. Panbru" <pa****@comcast.net> 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
Jul 18 '05 #3
David Abrahams wrote:
"T. Panbru" <pa****@comcast.net> 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

Jul 18 '05 #4
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



Jul 18 '05 #5
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 <fu****@sci.fi> wrote in message news:<lj*****************@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


Jul 18 '05 #6
Harri Pesonen <fu****@sci.fi> writes:
David Abrahams wrote:
"T. Panbru" <pa****@comcast.net> 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
Jul 18 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

17
by: Andrew Koenig | last post by:
Suppose I want to define a class hierarchy that represents expressions, for use in a compiler or something similar. We might imagine various kinds of expressions, classified by their top-level...
27
by: Brian Sabbey | last post by:
Here is a first draft of a PEP for thunks. Please let me know what you think. If there is a positive response, I will create a real PEP. I made a patch that implements thunks as described here....
2
by: Lenin | last post by:
Hi I have a quick question regarding static methods as part of a callback mechanism ( with particular reference to a web service, although it is not a web service question ). Basically I have an...
2
by: Peter | last post by:
Hello Thank for reviewing this question. I would like to know why I am getting a syntax error. For example public class public class B : public
1
by: Natalia DeBow | last post by:
Hi, I am working on a Windows-based client-server application. I am involved in the development of the remote client modules. I am using asynchronous delegates to obtain information from...
7
by: SB | last post by:
What is the proper way to pass a character array (char *) from a "C" dll to a C# method (delegate) in my app? Getting the dll (which simulates a third party dll) to call my delegate works fine. ...
10
by: Shawn Meyer | last post by:
Hello - I am trying to write a class that has an async BeginX and EndX, plus the regular X syncronous method. Delegates seemed like the way to go, however, I still am having problems getting...
14
by: Wildemar Wildenburger | last post by:
Hello folks :) This has got to be an FAQ, but somehow I can't seem to find an answer that I understand ... I thought: I'll just write a decorator that lets me react to method calls easily (the...
4
by: Immortal_Nephi | last post by:
You have written several global functions inside header code. Then, you create either static library or dynamic linked library. All global functions can be reuseable to the main() function when...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.