将 Cython class 对象作为参数传递给 C 函数
Passing Cython class object as argument to C function
我正在尝试将 Cython
实例 class 对象作为参数传递给 C
函数 - 因此它可以对其方法进行回调。
这是我试过的:
sample.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
的回调无效。你能发现我做错了什么或提出修复建议吗?
问题已解决。这是因为 class 中的方法被定义为 cdef
而不是 cpdef
.
sample.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)
我正在尝试将 Cython
实例 class 对象作为参数传递给 C
函数 - 因此它可以对其方法进行回调。
这是我试过的:
sample.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
的回调无效。你能发现我做错了什么或提出修复建议吗?
问题已解决。这是因为 class 中的方法被定义为 cdef
而不是 cpdef
.
#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)