이것은 예상했던 것보다 어렵지만 수행 할 수 있습니다. 당신이 선택하려는 경우
#include <python.h>
static PyObject *my_callback(PyObject *ignore, PyObject *args)
{
/* ... */
}
static struct PyMethodDef callback_descr = {
"function_name",
(PyCFunction) my_callback,
METH_VARARGS, /* or METH_O, METH_NOARGS, etc. */
NULL
};
static PyObject *py_callback;
...
py_callback = PyCFunction_New(&callback_descr, NULL);
이 방법은 작동하지 않습니다 : 당신이 콜백으로 제공 할 단일 C 기능이있는 경우
, 당신은 호출 파이썬로 변환 PyCFunction_New
을 사용할 수 있습니다 런타임에 다른 콜백, 예. C 콜백 함수를 파이썬 콜백으로 변환하는 일반 c_to_python
함수를 제공합니다. 이 경우 자체 tp_call
확장 유형을 구현해야합니다.
typedef struct {
PyObject_HEAD
static PyObject (*callback)(PyObject *, PyObject *);
} CallbackObject;
static PyObject *
callback_call(CallbackObject *self, PyObject *args, PyObject *kwds)
{
return self->callback(args, kwds);
}
static PyTypeObject CallbackType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"Callback", /*tp_name*/
sizeof(CallbackObject), /*tp_basicsize*/
0, /*tp_itemsize*/
0, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
(ternaryfunc) callback_call, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
};
PyObject *
c_to_python(PyObject (*callback)(PyObject *, PyObject *))
{
CallbackObject *pycallback = PyObject_New(CallbackObject, &CallbackType);
if (pycallback)
pycallback->callback = callback;
return pycallback;
}
이 코드는 하찮게도 user_data
포인터를 허용하도록 연장된다 사용자 데이터를 CallbackObject
구조체에 저장하면됩니다.
http://stackoverflow.com/questions/6626167/build-a-pyobject-from-a-c-function (병합해야 함, 모듈 포인트 외)을 참조하십시오. – ecatmur
@ecatmur 연결된 대답이 잘못되었습니다. 'methd'는'PyCFunction'이 제공된'PyMethodDef'에 대한 포인터를 보유하고 나중에 C 함수와 플래그를 검색하기 위해 정적으로 할당되어야합니다. 답안의 코드는'PyMethodDef'를 자동으로 할당합니다. 결과 Python 함수가 호출 될 때 충돌이 발생할 것입니다. – user4815162342
@ user4815162342 : 링크드 인 답변에서 Manux는 프로세스의 개요를 보여준 것 같습니다. 조금 어리석은 IMO입니다. Manux는 함수 이름을'NULL' 대신 모듈 이름으로 사용합니다. 실제 코드에서는'PyMethodDef'가 힙에 할당되었다고 가정합니다. – eryksun