Используйте Python C -API, чтобы получить текущий размер стека значений - PullRequest
2 голосов
/ 21 апреля 2020

Я играю с Python C -API. В частности, я хочу посмотреть, смогу ли я проверить, сколько элементов у стека значений в настоящее время. Вот мой код:

#include <Python.h>
#include <frameobject.h>

int test() {
    PyFrameObject* f = PyEval_GetFrame();
    return (int)(f->f_stacktop - f->f_valuestack);
}

Я не уверен, может ли это сработать, но эта строка существует в исходном коде Python , поэтому я попробовал.

Это обычно приводит к отрицательному числу, что-то вроде -547715639.

Итак, я явно ошибаюсь, вероятно, потому что то, что описано в документации: "Оценка кадра обычно NULLs (f_stacktop) ". Как правильно это сделать, или это вообще возможно?

Ответы [ 2 ]

0 голосов
/ 28 апреля 2020

Нет ничего невозможного ?‍♀️

Вот как я могу получить вещи из стека значений в скомпилированном модуле расширения:

    PyObject **stack_pointer = frame->f_stacktop;

    if (frame->f_stacktop == frame->f_valuestack) {
        PyErr_SetString(PyExc_ValueError, "stack is empty");
        return NULL;
    }

    if (!stack_pointer) {
        PyErr_SetString(PyExc_ValueError, "stack pointer is null?");
        return NULL;
    }

    // Top-most on the value stack ought to be the "receiver".
    PyObject *next = stack_pointer[-1];

Источник: https://github.com/dimaqq/awaitwhat/blob/e242ea7502cd13ebf7aca16700240aa592467f3a/awaitwhat/what.c#L24 -L37

А вот как получить его в Python, используя ctypes: { ссылка }

0 голосов
/ 22 апреля 2020

Это невозможно. См. этот ответ .

Короче, я должен использовать

(int)(stack_pointer - f->f_valuestack);

Однако stack_pointer - это локальное переменное внутри функции _PyEval_EvalFrameDefault, таким образом, не может быть доступен извне.

...