Let python call a C function pointer passed from the C Python API

Carl Banks pavlovevidence at gmail.com
Mon Nov 16 08:25:05 EST 2009


On Nov 16, 5:04 am, hvictor <hvic... at bluewin.ch> wrote:
> I have C++ a void function pointer stored in a variable call. The
> pointed function takes an int and a char* as arguments.
>
> I have a python module containing this function:
>
> def yeah(x):
>         x(int(0),"text argument")
>         return "pointer called"
>
> As you can see I'm trying to use the argument x of the function like a
> method object.
> In the C++ side I'm doing following (note that I only paste relevant
> parts of code because this system is working fine, C++ is able to call
> function yeah and get its return value, but only with a string-
> oriented test):
> ...
> PyObject *pValue; // the argument for python
>
> pValue = PyCObject_FromVoidPtr(call,destr); // destr is a void fctn
> ptr, required from the api.
>
> PyObject *pFunc = PyObject_GetAttrString(pModule, "yeah");
>
> ...
> PyTuple_SetItem(pArgs, 0, pValue); // pArgs is a pyobject, the
> arguments, I insert pValue in it.
>
> pValue = PyObject_CallObject(pFunc, pArgs);
>
> ...
>
> It does not work. can anyone help me please? I just want python to
> call this function pointer.

Python can't call C function pointers.  You have to write a function
in C that accepts a CObject and some arguments, unpacks the arguments,
retrieves the function pointer from the CObject, and calls it.  Quick
and dirty function that might do that (untested, not robust).


static PyObject* call_user_void_ptr(PyObject* self, PyObject* args) {
    PyObject* cobj;
    int ival;
    char* sval;
    void (*func)(int,char*);
    if (!PyArg_ParseTuple("O!is",&PyCObject_Type,&cobj,&ival,&sval))
        return 0;
    func = PyCObject_AsVoidPtr(cobj);
    func(ival,sval);
    Py_RETURN_NONE;
}


def yeah(x):
    call_user_void_ptr(x,int(i),"text_argument")
    print "pointer called"


In a pinch, you could call the function pointer from ctypes.  Since
you're already writing a C extension I wouldn't recommend it as a
final solution, though.


Carl Banks



More information about the Python-list mailing list