470,578 Members | 2,187 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,578 developers. It's quick & easy.

C Ext Questions

djw
Hello, I have a couple of questions about some code in a C extension module.
First, how would I convert a Python string return value from a call to
PyObject_CallFunction into a C void * buffer? Second, do I need to call
Py_XINCREF() on my callback function? (Sorry, the code is kind of
preliminary and rough)

Thanks,

Don
ext.c
-----

PyObject * callback = NULL;

PyObject * set_callback( PyObject * self, PyObject * args )
{
if( !PyArg_ParseTuple( args, "O", &callback ) )
{
return Py_BuildValue( "i", 1 );
}

if( !PyCallable_Check( callback ))
{
return Py_BuildValue( "i", 2 );
}

Py_XINCREF( callback );
}

int call_callback( int param1, int param2, void * buf, int size )
{
PyObject * result;

if( callback )
{
result = PyObject_CallFunction( callback, "ii", param1, param2 );
// Need to convert return Python string into buf....????
}
}

PyObject * do_something( PyObject * self, PyObject * args )
{
char buf[512];
call_callback( 1, 1, (void *)&buf, sizeof(buf) );
// buf should now contain: "This is the callback return string"
}

....
wrapper.py
----------

import ext

def f1():
return "This is the callback return string"

ext.set_callback( f1 )
ext.do_something()

....

Jul 18 '05 #1
2 1371
djw <do**********@hp.com> writes:
Hello, I have a couple of questions about some code in a C extension module.
First, how would I convert a Python string return value from a call to
PyObject_CallFunction into a C void * buffer?
PyString_AsString(). Do check for NULL return in case the the object
isn't a string...
Second, do I need to call Py_XINCREF() on my callback function?


Yes, though the code as posted would be fine with Py_INCREF().

Have you read the fine (well, ish) manuals on this sort of thing?

Cheers,
mwh

--
ARTHUR: Ford, you're turning into a penguin, stop it.
-- The Hitch-Hikers Guide to the Galaxy, Episode 2
Jul 18 '05 #2
> PyObject * set_callback( PyObject * self, PyObject * args )
{
if( !PyArg_ParseTuple( args, "O", &callback ) )
{
return Py_BuildValue( "i", 1 );
}
if( !PyCallable_Check( callback ))
{
return Py_BuildValue( "i", 2 );
}
Py_XINCREF( callback );
}
You are increasing the refcount here, but before you assign a new
callback, you will want to decrease the reference to the old callback.
Your other problem is that if PyArg_ParseTuple fails, it is raising an
exception. Your function _must_ return NULL or clear the exception.
Better to return NULL and let the exception get raised.

int call_callback( int param1, int param2, void * buf, int size )
{
PyObject * result;

if( callback )
{
result = PyObject_CallFunction( callback, "ii", param1, param2 );
// Need to convert return Python string into buf....????
}
}


You will need to get a char* pointer and copy that into your buffer.
char * str;
str = PyString_AsString(result);
if(!str)
{
Py_XDECREF(result);
return NULL;
}
strncpy((char*)buf, str, size-1);
((char*)buf)[size-1] = 0;
Py_DECREF(result);
return 1;
One last warning, if your program involves multiple threads, make sure
the Python callback only gets called from the primary thread. You'll
have a lot of "non-beginner" work to do to safely call the Python
callback from any thread. Anyways, this is probably not an issue.

Jul 18 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by softwareengineer2006 | last post: by
reply views Thread by softwareengineer2006 | last post: by
reply views Thread by softwareengineer2006 | last post: by
reply views Thread by connectrajesh | last post: by
reply views Thread by connectrajesh | last post: by
1 post views Thread by livre | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.