2012-05-11 5 views
1

Я читал через файл methodobject.c, потому что я пытаюсь узнать о создании расширений C для Python, когда я увидел следующий фрагмент кода:Похоже, что C-код в Python C-API возвращает переменную ptr в стек. Что мне не хватает?

PyObject * 
PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) 
{ 
    PyCFunctionObject* f = (PyCFunctionObject*)func; 
    PyCFunction meth = PyCFunction_GET_FUNCTION(func); 
    PyObject *self = PyCFunction_GET_SELF(func); 
    Py_ssize_t size; 

    switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) { 
    case METH_VARARGS: 
     if (kw == NULL || PyDict_Size(kw) == 0) 
      return (*meth)(self, arg); 
     break; 

Чем больше я смотрю на

return (*meth)(self, arg); 

Чем больше я понимаю, я не понимаю. I think возвращает указатель на meth, который является функцией, которая принимает self (локально объявленный указатель) и arg (указатель, проходящий внешне в PyCFunctionCall). Тем не менее, поскольку мне кажется, что в стекх выделяются меты, то после выключения PyCFunctionCall они будут освобождены, что вызовет проблемы для любых переменных, к которым они передаются.

Что мне здесь не хватает?

ответ

3

Возвращает возвращаемое значение meth(self, arg), а не meth. Обратите внимание, что он перенаправляет указатель на (*meth), а затем передает self и arg функции в этом месте.

Так что meth(self, arg) будет полностью оценен до того, как произойдет return, и никакие переменные стека не будут возвращены.

Редактировать: Когда я говорю meth(self, arg), я имею в виду the_function_pointed_to_by_meth(self, arg).

+0

Argh !!! Спасибо. Я чувствую себя идиотом, но, по крайней мере, теперь я просвещен. – user1245262

+0

Вот почему мы здесь. И как отмечает @ams, не чувствуйте себя слишком плохо; синтаксис указателя функции может ввести в заблуждение. – JoeFish

4

meth - указатель на функцию. Он возвращает результат функции на *meth (адрес, на который указывает мет), с аргументами: (self, arg);

+0

Спасибо. Я действительно ударился головой о стену здесь. Теперь я чувствую себя немного глупо, спрашивая об этом, но мне понадобилось время, чтобы поймать мое неправильное восприятие. – user1245262

2

(*meth)(self, arg) является функцией call.

Как раз так бывает, что указатель функции является локальной переменной. return просто передает все, что возвращается от вызова.

Синтаксис указателя функции в замешательстве. :)

+0

Спасибо. Сейчас я чувствую себя немного глупо, но, к счастью, меньше смущен. – user1245262