Нарушение прав доступа в PyRun_String () - PullRequest
1 голос
/ 10 июня 2019

У меня ошибка нарушения доступа в коде C, вызывающем Python.

Я пытаюсь вызвать функцию sympy из Python и обработать результат в C.

#include <Python.h>

int main(int argc, char *argv[])
{
    PyObject *pmod, *pdict, *pValue;
    Py_Initialize();
    pmod  = PyImport_ImportModule("sympy");
    PyErr_Print();
    pdict = PyModule_GetDict(pmod);

    pValue = PyRun_String("x = symbols('x'); diff(cos(x), x)", Py_single_input, pdict, pdict);
    PyErr_Print();
    if (pValue != NULL) {
        //PyObject* pu = PyUnicode_AsEncodedString(pValue, "utf-8", "~E~");
        //printf("Result of call: %s\n", PyBytes_AS_STRING(pu));
        //Py_DECREF(pu);
        Py_DECREF(pValue);
        Py_DECREF(pmod);
        Py_DECREF(pdict);
    }
    else {
        PyErr_Print();
        return 1;
    }
    Py_FinalizeEx();
    return 0;
}

Я хотел бы знать причину этого нарушения доступа и способы его устранения. Я также хотел бы знать, почему закомментированный printf, показывающий результат, не работает.

Моя строка компиляции:

gcc probe.c `python3-config --cflags` `python3-config --ldflags` -fpic

Моя версия Python - 3.6.7.

Заранее спасибо.

1 Ответ

2 голосов
/ 10 июня 2019

Проблема в том, что вы уничтожаете словарь модуля sympy, когда этого не должно быть.Согласно документации для PyModule_GetDict, возвращаемая словарная ссылка - заимствованная , а не новая.Поэтому вы не должны звонить Py_DECREF на это.Удаление строки с Py_DECREF(pdict); устраняет проблему.

Подробнее о владении и заимствовании из документации Python :

Владение также может быть передано, что означает, чтокод, который получает право собственности на ссылку, становится ответственным за ее окончательное удаление, вызывая Py_DECREF() или Py_XDECREF(), когда она больше не нужна, или передавая эту ответственность (обычно ее вызывающей стороне).Когда функция передает владение ссылкой своему вызывающему, говорят, что вызывающий получает новую ссылку.Когда право собственности не передается, звонящий, как говорят, заимствует ссылку.Ничего не нужно делать для заимствованной ссылки.

...