我正试图将Cython实例类对象作为参数传递给C函数,以便它可以回调其方法。
这就是我尝试过的:
样品c

#include "python.h"

void c_func(PyObject *obj){
    PyGILState_STATE gstate;
    gstate = PyGILState_Ensure();

    /* Dictionary Object - can be of any dynamic type */

    PyObject *dict_obj = PyDict_New();
    PyObject *key = PyUnicode_FromString("average-run");
    PyObject *val = PyLong_FromLong(45445);
    PyDict_SetItem(dict_obj, key, val);

    /* Make a callback */

    PyObject_CallMethod(obj, "func_a", "(d)", dict_obj);

    PyGILState_Release(gstate);
}

pysample.pxd文件
cdef extern from "sample.h":
    void c_func(object obj)

cdef class Test(object):
    cdef func_a(self, object dict_obj)

pysample.pyx文件
cimport pysample
from pysample cimport Test

cdef class Test(object):
    cdef func_a(self, object dict_obj):
        print(dict_obj)

    def run_test(self):
        # Here I make a call to the C function
        pysample.c_func(self)

不幸的是,来自C的回调不起作用。你能发现我做错了什么吗?或者建议解决这个问题?

最佳答案

这个问题已经解决了。这是因为类中的方法被定义为cdef而不是cpdef
样品c

#include "python.h"

void c_func(PyObject *obj){
    PyGILState_STATE gstate;
    gstate = PyGILState_Ensure();

    /* Dictionary Object - can be of any dynamic type */

    PyObject *dict_obj = PyDict_New();
    PyObject *key = PyUnicode_FromString("average-run");
    PyObject *val = PyLong_FromLong(45445);
    PyDict_SetItem(dict_obj, key, val);

    /* Make a callback */

   PyObject *res = PyObject_CallMethod(obj, "func_a", "(O)", dict_obj);

   if( !res )
   {
       PyErr_Print();
   }else
   {
      Py_DECREF(res);
   }
   /*
    * Note: Do not remove reference counting
    * for callback argument - python will take
    * care of it when the callback python method
    * go out of scope. If you do - it will cause
    * inconsistent data behaviour at the callback
    * method side.
    */

   PyGILState_Release(gstate);
}

pysample.pxd文件
cdef extern from "sample.h":
    void c_func(object obj)

cdef class Test(object):
    cpdef func_a(self, object dict_obj)

pysample.pyx文件
cimport pysample
from pysample cimport Test

cdef class Test(object):
    cpdef func_a(self, object dict_obj):
        print(dict_obj)

    def run_test(self):
        # Here I make a call to the C function
        pysample.c_func(self)

10-04 23:01