简体   繁体   English

PyRun_String()中的访问冲突

[英]Access violation in PyRun_String()

I've got an access violation error in a C code calling Python. 我在调用Python的C代码中遇到访问冲突错误。

I am trying to call a sympy function from Python and handle the result in C. 我正在尝试从Python调用sympy函数并在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;
}

I would like to know the reason for this access violation and how to solve it. 我想知道这种访问冲突的原因以及如何解决。 I would also like to know why the commented printf to show the result is not working. 我也想知道为什么注释后的printf不能显示结果。

My compilation line is: 我的编译行是:

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

My Python version is 3.6.7. 我的Python版本是3.6.7。

Thanks in advance. 提前致谢。

The problem is that you are destroying the sympy module's dictionary when you should not be. 问题是您不应该破坏sympy模块的字典。 According to the documentation for PyModule_GetDict , the returned dictionary reference is borrowed , not new. 根据PyModule_GetDict文档 ,返回的字典引用是借来的 ,而不是新的。 Therefore you must not call Py_DECREF on it. 因此,您不得在其上调用Py_DECREF Removing the line with Py_DECREF(pdict); Py_DECREF(pdict);删除行Py_DECREF(pdict); fixes the issue. 解决此问题。

More about ownership and borrowing from the Python documentation : 有关所有权和借用的更多信息,请参阅Python文档

Ownership can also be transferred, meaning that the code that receives ownership of the reference then becomes responsible for eventually decref'ing it by calling Py_DECREF() or Py_XDECREF() when it's no longer needed—or passing on this responsibility (usually to its caller). 所有权也可以转移,这意味着接收引用所有权的代码随后负责通过在不再需要时调用Py_XDECREF()Py_XDECREF()Py_XDECREF()将此责任(通常传递给调用者Py_DECREF()来最终对其进行引用)。 When a function passes ownership of a reference on to its caller, the caller is said to receive a new reference. 当函数将引用的所有权传递给其调用方时,该调用方被称为接收新的引用。 When no ownership is transferred, the caller is said to borrow the reference. 如果没有所有权转移,则称调用者借用了引用。 Nothing needs to be done for a borrowed reference. 无需做任何借用的参考。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM