简体   繁体   中英

C and Python integration: name of callback function

I am working on a project which requires Python with C integration. I have got it mostly working except for one issue below: How do I get the string representation of the callback function object in the C code. (See my comment in the code)

import mymodule
c=0

def double_it():
   c = c * 2
   return

def multiply(a, b):
   global c
   c = a*b
   mymodule.print_result(c, double_it)
   return

Where mymodule.print_result is defined as:

static PyObject*
print_result(PyObject* self, PyObject* args)
{
    PyObject *pCallBackFunc, *pArgs;
    int restult;
    char *func_name = NULL; // I want to fill this

    if (!PyArg_ParseTuple(args, "iO", &result, &pCallBackFunc))
    {
         printf ("ERRPR\n");
         return NULL;
     }

 if (PyCallable_Check(pCallBackFunc)) {
    Py_XINCREF(pCallBackFunc);

     // func_name = .... How to get the of the call back function that is "double_it" ??? 

   PyObject_CallObject(pCallBackFunc, pArgs);
   Py_XDECREF(pCallBackFunc);
   return Py_None;
}

Any help is greatly appreciated.

使用Python的方式相同,但使用C的方式相同。

PyObject_GetAttrString(pCallBackFunc, "__name__")

You could look at how the func_get_name function is implemented.

So to access the name of a function simply use:

PyObject *
get_function_name(PyFunctionObject *fun) {
    Py_INCREF(fun->func_name);
    return fun->func_name;
}

To be used as:

if (!PyArg_ParseTuple(args, "iO", &result, &pCallBackFunc))
{
     printf ("ERRPR\n");
     return NULL;
}

if (PyFunction_Check(pCallBackFunc)) {

   func_name = get_function_name((PyFunctionObject *)pCallBackFunc);

   PyObject_CallObject(pCallBackFunc, pArgs);
   Py_RETURN_NONE;
}

However func_name is a PyObject * . So you'd have to also convert it into a char * .


Note: you do not want to use PyCallable_Check because only functions have a name. Other callables need not have it. If you want to be able to handle generic callables and obtain the name only in the case of functions you still have to explicitly check for PyFunction s and then for generic callables.


The above solution avoids the attribute lookup and thus it should be quite more efficient than calling PyObject_GetAttr* .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM