By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
464,706 Members | 1,299 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 464,706 IT Pros & Developers. It's quick & easy.

Function References

P: n/a
Greetings,

I'm trying to wrap a function in a C library as a compiled C Python
module. Everything is going great, but I've hit a snag. There's a
function in the form of this:

First the typedef:
typedef void(*FPtr_DeviceMessageHandler) (const DeviceMessage, const
char*);

Then the actual function prototype:
FPtr_DeviceMessageHandler
RegisterDeviceMessageHandler(FPtr_DeviceMessageHan dler);

Whenever this USB device I'm using generates a message, it's then sent
to that function whose reference you passed to
RegisterDeviceMessageHandler(). Here's an example:

void testfunc() {
printf("test");
}
....on to main()
RegisterDeviceMessageHandler(&testfunc)

So I've defined a similar function on my C module to do just this,
using the passed function reference to allow the device to send
messages to a Python function of the user's choice. I'm just not sure
how to do this, and the tutorials I've been digging through don't
offer any help. I've found some functions that look promising, but
can't figure out how to cast the function reference from Python into
something the C RegisterDevice... function can handle. Here's what
I've got:

static PyObject *
Py1_RegisterDeviceMessageHandler(PyObject *self, PyObject *args)
{
PyObject *handle, *parsed;

if(!PyArg_ParseTuple(args, "O", handle)) {
return NULL;
}

parsed = PyMethod_Function(handle);
I1_RegisterDeviceMessageHandler(PyMethod_Function( handle));

Py_RETURN_TRUE;
} // end Py1_RegisterDeviceMessageHandler()

This fails since PyMethod_Function returns a PyObject. Is there a way
to cast this to something generic? Casting to (void*) didn't seem to
work.

Thanks in advance!
Jul 31 '08 #1
Share this Question
Share on Google+
14 Replies

P: n/a
sq***********@gmail.com wrote:
Greetings,

I'm trying to wrap a function in a C library as a compiled C Python
module. Everything is going great, but I've hit a snag. There's a
function in the form of this:

First the typedef:
typedef void(*FPtr_DeviceMessageHandler) (const DeviceMessage, const
char*);

Then the actual function prototype:
FPtr_DeviceMessageHandler
RegisterDeviceMessageHandler(FPtr_DeviceMessageHan dler);

Whenever this USB device I'm using generates a message, it's then sent
to that function whose reference you passed to
RegisterDeviceMessageHandler(). Here's an example:

void testfunc() {
printf("test");
}
...on to main()
RegisterDeviceMessageHandler(&testfunc)

So I've defined a similar function on my C module to do just this,
using the passed function reference to allow the device to send
messages to a Python function of the user's choice. I'm just not sure
how to do this, and the tutorials I've been digging through don't
offer any help. I've found some functions that look promising, but
can't figure out how to cast the function reference from Python into
something the C RegisterDevice... function can handle. Here's what
I've got:

static PyObject *
Py1_RegisterDeviceMessageHandler(PyObject *self, PyObject *args)
{
PyObject *handle, *parsed;

if(!PyArg_ParseTuple(args, "O", handle)) {
return NULL;
}

parsed = PyMethod_Function(handle);
I1_RegisterDeviceMessageHandler(PyMethod_Function( handle));

Py_RETURN_TRUE;
} // end Py1_RegisterDeviceMessageHandler()

This fails since PyMethod_Function returns a PyObject. Is there a way
to cast this to something generic? Casting to (void*) didn't seem to
work.

Thanks in advance!
May I suggest you move to ctypes for wrapping? It's easier, pure python and
callbacks are already built-in.

Diez
Jul 31 '08 #2

P: n/a
Hello Diez.
May I suggest you move to ctypes for wrapping? It's easier, pure python and
callbacks are already built-in.
I'm pretty new to extending Python in C, I don't understand what
you're saying. Are there any examples or a brief explanation/URL you
could point me to?

Jul 31 '08 #3

P: n/a
sq***********@gmail.com wrote:
Hello Diez.
>May I suggest you move to ctypes for wrapping? It's easier, pure python
and callbacks are already built-in.

I'm pretty new to extending Python in C, I don't understand what
you're saying. Are there any examples or a brief explanation/URL you
could point me to?
Is google dead today?

http://www.google.com/search?q=pytho...UTF-8&oe=UTF-8

First hit.

Ctypes is a since python2.5 built-in module that allows to declare
interfaces to C-libraries in pure python. You declare datatypes and
function prototypes, load a DLL/SO and then happily work with it. No C, no
compiler, no refcounts, no nothing.

And you can pass python-functions as callbacks.

See the module docs for examples.

Diez
Jul 31 '08 #4

P: n/a
Ctypes is a since python2.5 built-in module that allows to declare
interfaces to C-libraries in pure python. You declare datatypes and
function prototypes, load a DLL/SO and then happily work with it. No C, no
compiler, no refcounts, no nothing.

And you can pass python-functions as callbacks.
The first sentence (and some really crummy licensing restrictions
imposed by the library distributor) alone here excludes this as a
valid option for this particular case, I definitely need Python 2.4
support.

So the question comes back around to being how is this same desired
behavior duplicated in the Python/C API?
Jul 31 '08 #5

P: n/a
sq***********@gmail.com wrote:
>Ctypes is a since python2.5 built-in module that allows to declare
interfaces to C-libraries in pure python. You declare datatypes and
function prototypes, load a DLL/SO and then happily work with it. No C,
no compiler, no refcounts, no nothing.

And you can pass python-functions as callbacks.

The first sentence (and some really crummy licensing restrictions
imposed by the library distributor) alone here excludes this as a
valid option for this particular case, I definitely need Python 2.4
support.
How much more liberal can it get than MIT-licensed?

"""
to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
"""

But then, if you insist, go down the hard road.

Diez

Jul 31 '08 #6

P: n/a
Diez B. Roggisch wrote:
sq***********@gmail.com wrote:
>>Ctypes is a since python2.5 built-in module that allows to declare
interfaces to C-libraries in pure python. You declare datatypes and
function prototypes, load a DLL/SO and then happily work with it. No C,
no compiler, no refcounts, no nothing.

And you can pass python-functions as callbacks.

The first sentence (and some really crummy licensing restrictions
imposed by the library distributor) alone here excludes this as a
valid option for this particular case, I definitely need Python 2.4
support.

How much more liberal can it get than MIT-licensed?

"""
to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
"""
Sorry, missed the paragraph

"""
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
"""

Still, AFAIK MIT is pretty liberal.

Diez
Jul 31 '08 #7

P: n/a
How much more liberal can it get than MIT-licensed?

Again, the licensing issue is everything to do with the original
library distributor, NOT ctypes.
But then, if you insist, go down the hard road.
Irrelevant and unnecessary. If you don't want to help, don't please
don't reply.
Jul 31 '08 #8

P: n/a
sq***********@gmail.com wrote:
>How much more liberal can it get than MIT-licensed?

Again, the licensing issue is everything to do with the original
library distributor, NOT ctypes.
I read library distributor as "ctypes-library distributor" because it is
3rd-party under 2.4. Which was the reason I quotet it's MIT-license.

And it escapes me what accessing the lib from ctypes is any different than
from your own compiled code.
>But then, if you insist, go down the hard road.

Irrelevant and unnecessary. If you don't want to help, don't please
don't reply.
I take the freedom to do so as I see fit - this is usenet...

Diez
Jul 31 '08 #9

P: n/a
On Jul 31, 10:47*am, "Diez B. Roggisch" <de...@nospam.web.dewrote:
I take the freedom to do so as I see fit - this is usenet...
Fine, then keep beating a dead horse by replying to this thread with
things that do nobody any good. It seems like there are a lot better
way to waste time, though.

The Python/C API can get me back further without reliance on third-
party libraries than ctypes. It also isn't subject to the quirks that
ctypes is on platforms other than Windows (the target application runs
on Windows, Mac, and eventually Linux once the original distributor
has drivers for the device). I'm not even sure ctypes could load the
lib/driver the distributor packaged.

So really, I appreciate the option in ctypes, it's good stuff. But
it's not for this project.

Once again, the original question stands for anyone who has experience
with the Python/C API callbacks.
Jul 31 '08 #10

P: n/a
>Ctypes is a since python2.5 built-in module that allows to declare
>interfaces to C-libraries in pure python. You declare datatypes and
function prototypes, load a DLL/SO and then happily work with it. No C, no
compiler, no refcounts, no nothing.

And you can pass python-functions as callbacks.
sq***********@gmail.com wrote:
The first sentence (and some really crummy licensing restrictions
imposed by the library distributor) alone here excludes this as a
valid option for this particular case, I definitely need Python 2.4
support.
Perhaps all is not lost: ctypes works from Python 2.3 up. That first
sentence is saying that since Python 2.5 it has been included in the
standard Python distribution, but you can still download it separately.

-M-
Jul 31 '08 #11

P: n/a
sq***********@gmail.com wrote:
Greetings,

I'm trying to wrap a function in a C library as a compiled C Python
module. Everything is going great, but I've hit a snag. There's a
function in the form of this:

First the typedef:
typedef void(*FPtr_DeviceMessageHandler) (const DeviceMessage, const
char*);

Then the actual function prototype:
FPtr_DeviceMessageHandler
RegisterDeviceMessageHandler(FPtr_DeviceMessageHan dler);
[...]
[i] can't figure out how to cast the function reference from Python into
something the C RegisterDevice... function can handle.
Mere casting won't do the trick. The function reference from Python is
basically just an object that contains byte-code to be executed by the
Python Virtual Machine. There is no way you can magically transform that
into a C function by casting the Python object pointer to anything.

You'll need a write a C function that will call a given Python function,
and then you need to supply the pointer to that C function as your
DeviceMessageHandler callback function, and somehow communicate to your
C function which Python function it should call.

Good luck.

--
Carsten Haese
http://informixdb.sourceforge.net
Jul 31 '08 #12

P: n/a
sq***********@gmail.com schrieb:
On Jul 31, 10:47 am, "Diez B. Roggisch" <de...@nospam.web.dewrote:
>I take the freedom to do so as I see fit - this is usenet...

Fine, then keep beating a dead horse by replying to this thread with
things that do nobody any good. It seems like there are a lot better
way to waste time, though.
You mean like trying to wrap ones head around the rather simple Python C
API, not getting a callback mechanism implemented?

For the record: I've wrapped C-libs myself, including callbacks. Been
there, done that, discovered (years later) cytpes, been there for good.
The Python/C API can get me back further without reliance on third-
party libraries than ctypes.
You don't consider your own library a third party lib? And unless you're
wrapping C++, you're opinion is as uninformed as it is wrong.
It also isn't subject to the quirks that
ctypes is on platforms other than Windows (the target application runs
on Windows, Mac, and eventually Linux once the original distributor
has drivers for the device). I'm not even sure ctypes could load the
lib/driver the distributor packaged.
Oh please. I'm 98% working on linux & osx. ctypes does a great job on
these platforms.

Regarding your objections I can only say: whatever the python runtime
can load because of the underlying ld, ctypes can load. simply because
they are the same. If *that* was the actual cause of problems, we
wouldn't even talk about callbacks here.
So really, I appreciate the option in ctypes, it's good stuff. But
it's not for this project.
Stop finding lame excuses for not wanting to ditch the work you've done
in favor of a easier solution. You like your code, you want to keep it,
you want to discover the intricasies of the Python C API? Be my guest.

But stop embarassing yourself inventing reasons like licensing or linker
problems you don't support with any facts whatsoever.
Once again, the original question stands for anyone who has experience
with the Python/C API callbacks.
You know what? Just for the fun of it, I'll take a stab at it.

It's easy: Create a "proxy-function" that matches the prototype of the
c8allback which converts the passed arguments to python values using the
C-api. Then call the registered python function using
PyObject_CallFunction.

Convert the return-value back to C, and return it.

Make the function get the PyObject* for the call fetch from a global
variable you set in the register-callback function, where you also
register the proxy-function for the first time, or de-register if the
passed value is None or such.

Have fun.
Diez
Jul 31 '08 #13

P: n/a
Lie
On Aug 1, 6:35*am, "Diez B. Roggisch" <de...@nospam.web.dewrote:
squishywaf...@gmail.com schrieb:
On Jul 31, 10:47 am, "Diez B. Roggisch" <de...@nospam.web.dewrote:
I take the freedom to do so as I see fit - this is usenet...
Fine, then keep beating a dead horse by replying to this thread with
things that do nobody any good. It seems like there are a lot better
way to waste time, though.

You mean like trying to wrap ones head around the rather simple Python C
API, not getting a callback mechanism implemented?

For the record: I've wrapped C-libs myself, including callbacks. Been
there, done that, discovered (years later) cytpes, been there for good.
The Python/C API can get me back further without reliance on third-
party libraries than ctypes.

You don't consider your own library a third party lib? And unless you're
wrapping C++, you're opinion is as uninformed as it is wrong.
It also isn't subject to the quirks that
ctypes is on platforms other than Windows (the target application runs
on Windows, Mac, and eventually Linux once the original distributor
has drivers for the device). I'm not even sure ctypes could load the
lib/driver the distributor packaged.

Oh please. I'm 98% working on linux & osx. ctypes does a great job on
these platforms.

Regarding your objections I can only say: whatever the python runtime
can load because of the underlying ld, ctypes can load. simply because
they are the same. If *that* was the actual cause of problems, we
wouldn't even talk about callbacks here.
So really, I appreciate the option in ctypes, it's good stuff. But
it's not for this project.

Stop finding lame excuses for not wanting to ditch the work you've done
in favor of a easier solution. You like your code, you want to keep it,
you want to discover the intricasies of the Python C API? Be my guest.

But stop embarassing yourself inventing reasons like licensing or linker
problems you don't support with any facts whatsoever.
Once again, the original question stands for anyone who has experience
with the Python/C API callbacks.

You know what? Just for the fun of it, I'll take a stab at it.

* It's easy: Create a "proxy-function" that matches the prototype of the
c8allback which converts the passed arguments to python values using the
C-api. Then call the registered python function using
PyObject_CallFunction.

Convert the return-value back to C, and return it.

Make the function get the PyObject* for the call fetch from a global
variable you set in the register-callback function, where you also
register the proxy-function for the first time, or de-register if the
passed value is None or such.

Have fun.

Diez
Zen's lesson for today:
THOU SHALT NOT MESS WITH ANY PYTHON'S SEMI-GODS, DEMI-GODS, AND
PYTHON'S GOD.

You're lucky Diez still want to help you with your attitude like that.
May I remind you that we here helps you for free in our free time, be
rude, especially to a frequent member, and you'll get what you deserve.
Aug 28 '08 #14

P: n/a
Zen's lesson for today:
THOU SHALT NOT MESS WITH ANY PYTHON'S SEMI-GODS, DEMI-GODS, AND
PYTHON'S GOD.

You're lucky Diez still want to help you with your attitude like that.
May I remind you that we here helps you for free in our free time, be
rude, especially to a frequent member, and you'll get what you deserve.
Thanks Lie, but I certainly don't consider myself being part of Python's
olymp... :) Others here of course are, and a friendly and open attitude
from everybody sure helps keeping this institution helpful.

This goes also for frequent members - and I do include myself here, as I
*sometimes* forget that myself, but try hard not to.

Diez
Aug 28 '08 #15

This discussion thread is closed

Replies have been disabled for this discussion.