【发布时间】:2015-11-22 08:07:22
【问题描述】:
我正在尝试将 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 的回调不起作用。你能发现我做错了什么或建议解决这个问题吗?
【问题讨论】:
-
c_func 函数应该如何作为测试方法附加到这里? self.c_func 似乎应该给出属性错误。编译、导入、尝试调用时能显示错误吗?
-
我错过了 pysample 的独立 cimport - 我将使用它编辑线程。谢谢
-
我们仍然需要实际看到您编译、加载和调用 run_test,以便我们可以尝试帮助调试。
-
文档中的两件事可能会有所帮助。 1) 格式字符串中的“d”被解释为浮点数,而不是字典 (docs.python.org/2/c-api/arg.html#c.Py_BuildValue)。 2)“请注意,如果你只通过
PyObject * args,PyObject_CallMethodObjArgs()是一个更快的选择。” (docs.python.org/2/c-api/object.html) -
我强烈怀疑如果您将 callmethod 行更改为:
PyObject_CallMethod(obj, "func_a", "(O)", dict_obj);(将 dict 作为通用 Python 对象传递),它将起作用。