[PyKDE] More sip on C fun!
Jonathan Gardner
jgardner at jonathangardner.net
Sat May 31 10:50:00 BST 2003
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On Tuesday 20 May 2003 00:37, Phil Thompson wrote:
> On Tuesday 20 May 2003 3:22 am, Jonathan Gardner wrote:
> > 3) There is a callback function that I would like to use. How would I
> > go about doing this in sip? What kind of function should I put as the
> > callback? What kind of arguments should I expect from sip?
> >
> > Let's just keep it simple:
> >
> > The callback prototype: typedef void (*callback_func)(int);
> >
> > The "set callback" prototype: int set_callback(callback_func *);
> > (And there is a corresponding release_callback() function as well, of
> > course).
> >
> > What I would like to see in python:
> >
> > def callback(x): print x
> > set_callback(callback)
> >
> > how do I get from C to Python via sip?
>
> You will have to store the Python callback object somewhere (remembering
> that there may be several of them around at a time). You will have to
> provide a C callback that is permanently installed which will find the
> correct Python callback object and use the standard Python API to call it
> - after having converted the C callback arguments to the appropriate
> Python equivalents.
>
> Phil
>
Okay, I gave it a go.
The actual prototype for the callback is:
typedef void (*PQnoticeProcessor) (void *arg, const char *message);
The actual function to set the callback is:
extern PQnoticeProcessor PQsetNoticeProcessor(PGconn *conn,
PQnoticeProcessor proc,
void *arg);
'arg' is whatever I want it to be. In this case, it is going to be a pointer
to the "Conn" object I am wrapping.
I add a member to Conn: PyObject noticeProcessor
I make sure all the constructors set it to Py_None.
I add the following method:
void setNoticeProcessor(PyObject *np) {
// Don't change anything if it is the same thing
if (np == noticeProcessor)
return;
if (np == Py_None) {
// Clear it out
Py_DECREF(noticeProcessor);
noticeProcessor = Py_None;
Py_INCREF(noticeProcessor);
PQsetNoticeProcessor(conn, NULL, NULL);
} else {
// Set it up
Py_DECREF(noticeProcessor);
noticeProcessor = np;
Py_INCREF(noticeProcessor);
PQsetNoticeProcessor(conn, pyNoticeProcessor, (void *)this);
}
}
Looks pretty good, I think. Suggestions welcome, of course.
I put this in the sip file:
void setNoticeProcessor(int);
%MemberCode
PyObject *np;
Conn *ptr;
if (sipParseArgs(&sipArgsParsed,sipArgs,
"mO",
sipThisObj,sipClass_Conn,&ptr,
&np))
{
if (np != Py_None && !PyCallable_Check(np)) {
PyErr_SetString(PyExc_ValueError,
"NoticeProcessor must be a callable or None.");
return NULL;
}
ptr->setNoticeProcessor(np);
return Py_None;
}
%End
I try to compile it. It complains about a double declaration of
"pyNoticeProcessor". I had to put a declaration before Conn. So I switch it
around - declare Conn, describe pyNoticeProcessor, then describe Conn. That
won't work either.
So I move the 'pyNoticeProcessor' body into a %C++Code section in the sip
file. The code doesn't show up anywhere in the cc files (it is declared
outside of any class). I thought it would put the body in sippqcmodule.cc
or something like that, which is what I really want (I think).
But anyway, it compiles fine. It is only when I try to use it that it
realizes there is no definition for pyNoticeProcessor. That is of course
because the code wasn't put in any cc file that I could see.
Any suggestions? I wanted to avoid making a new cc file manually, mostly
because I am lazy. I am hoping there is a mechanism in sip to handle this
sort of thing and throw it into sippqcmodule.cc.
I finish this, and I will be done with the PostgreSQL interface, at least as
far as it is reasonable to take it. I will release it to this list, and to
the world immediately thereafter.
Must sleep now... nearly 2:00 AM...
- --
Jonathan Gardner
jgardner at jonathangardner.net
(was jgardn at alumni.washington.edu)
Live Free, Use Linux!
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.7 (GNU/Linux)
iD8DBQE+2G1YWgwF3QvpWNwRAjkXAKDXbUUUfvmmLxpbv7P6rnU32bZsgACg2c2Q
rdEIQX5VDM969JlRtg2OXf0=
=GfLH
-----END PGP SIGNATURE-----
More information about the PyQt
mailing list