Segfault when trying to call a Python function from C

久未见 提交于 2019-12-08 07:41:09

问题


So, I want to call a Python callback function from C.

At some point, the function is sent to C and packed into a tuple like this

PyObject *userData = Py_BuildValue("Oi",py_callback,some_number);

Somewhere in that area, I do Py_INCREF(py_callback), too.
At some later time in the program, I want to call that function

PyObject *py_callback;
int some_number;
PyArg_ParseTuple((PyObject*)userData,"Oi",&py_callback,&some_number); // returns true
PyObject *py_result = PyObject_CallFunctionObjArgs(py_callback,
                                                   /* ... */
                                                   NULL);

and that last call throws a segmentation fault. Do you have any idea, why it would do such a thing?


回答1:


When getting weird behaviour from the Python C API, it is always worth double checking that you are managing the state of the Global Interpreter Lock (aka "the GIL") correctly: http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock




回答2:


I'm not sure why everyone is talking about the GIL here. Are you releasing it anywhere? I notice a few possible trouble points which I'll list below. It's intermingled with suggestions.

I notice that you're not incrementing the reference count of userData. Why not? You are storing it aren't you? Why do you want to store it in the tuple? Why not just keep two variables (for callback and data) and then increment their refcounts so that you own a reference?

First of all, check the return values of all your functions to see if they're NULL. This will let you make sure that you're actually running properly. It's also probably a good idea to use PyObject_Print to print the objects you're interested in at all the points in the code to make sure things are going as you expect.

From your comment on where the segfault happens, my guess is that you're passing the wrong number of parameters to your callback function when you call it with PyObject_CallFunctionObjArgs. Can you double check it? Maybe show us your callback function definition and then check the invocation again.

Another possible issue I see is that from the naming, py_some_number sounds like you expect a Python integer object. This is not the case. After the PyArg_ParseTuple, it will contain an integer.



来源:https://stackoverflow.com/questions/5090585/segfault-when-trying-to-call-a-python-function-from-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!