我正在尝试更改Python代码从C库调用的函数的函数回调类型。我是从Python文档中引用以下code。
下面的代码似乎可以正常运行,但由于某些分段错误而有些不稳定。
PYTHON代码(之前)
class MM(object):
def __init__(self, curpath):
self._mmlib = cdll.LoadLibrary(curpath + '/libraryfile.so')
self._project_init = self._mmlib.project_init
self._project_setCallback = self._mmlib.project_setCallback
.
.
self._projectintrdata = PROJECT_INTR_DATA(0,0,0)
.
.
def project_setcallback(self, projectcallback):
ck_type = CFUNCTYPE(c_int, c_void_p)
callback = ck_type(projectcallback)
self._project_setCallback(callback, pointer(self._projectintrdata))
.
.
C代码(之前)
typedef struct project_intr_data{
uint8_t val;
uint8_t state;
int count;
}project_intr_data;
.
.
.
int si3050_init(si3050_data *ptr)
{
//initialization stuff...
}
void project_setCallback(void (*function)(void*ptr), void* arg)
{
Callback_Rd = function;
gPtr = (project_intr_data*)arg;
}
我正在对此进行更改,以便从C端调用的函数是Python对象指针类型。
PYTHON代码(后)
class ModemManager(object):
def __init__(self, curpath):
self._mmlib = cdll.LoadLibrary(curpath + '/libraryfile.so')
self._project_init = self._mmlib.project_init
self._project_setCallback = self._,,lib.project_setPyObject
.
.
.
def project_setcallback(self, projectcallback):
ck_type = CFUNCTYPE(py_object, POINTER(py_object), POINTER(py_object))
callback = ck_type(projectcallback)
self._project_setCallback(callback, pointer(callback))
.
.
.
C代码(之后)
PyObject * project_setPyObject( PyObject *dummy, PyObject *args)
{
PyObject *result = NULL;
PyObject *temp;
if(PyArg_ParseTuple(args, "O:project_setPyObject", &temp)){
if (!PyCallable_Check(temp)) {
PyErr_SetString(PyExc_TypeError, "parameter must be callable");
return NULL;
}
Py_XINCREF(temp); /* Add a reference to new callback */
Py_XDECREF(Callback); /* Dispose of previous callback */
Callback = temp; /* Remember new callback */
Py_INCREF(Py_None);
result = Py_None;
}
return result;
}
尝试更改函数指针类型是为了查看是否会降低我遇到的分段错误频率。
但是,每次在[project_setcallback]内部,新代码都会导致碎片错误。 导致分段错误的确切行是下面的行。我认为回调函数的类型存在问题,但是我有限的编程技能并没有使我更进一步。
self._project_setCallback(callback, pointer(callback))