【问题标题】:Py_BuildValue segmentation faultPy_BuildValue 分段错误
【发布时间】:2022-01-01 21:46:59
【问题描述】:

我正在尝试从 C 程序运行一个简单的 Python 代码,但在 pArgs = Py_BuildValue("s",(char*)"Greg"); 行出现分段错误

这是我要运行的python代码:

def main(person):
    return "What's up " + person;

这是我的 C 程序:

#include <stdio.h>
#include <Python.h>

void main(void) {
        Py_Initialize();
        PyObject *pName, *pModule, *pFunc, *pArgs, *pValue;
        pName = PyUnicode_FromString((char*)"main");
        pModule = PyImport_Import(pName);
        pFunc = PyObject_GetAttrString(pModule, (char*)"main");
        pArgs = Py_BuildValue("s",(char*)"Greg"); 
        pValue = PyObject_CallObject(pFunc, pArgs);                   
        Py_Finalize();
        return;
}

我正在开发 Ubuntu 20.4

从Idle启​​动的python代码可以运行,文件在同一目录下python文件名为main.py

你能告诉我我做错了什么吗?

【问题讨论】:

  • 为了排除其他可能的问题,您应该检查所有 C API 调用的返回值是否为 NULL,以防出现问题。 Py_BuildValue 中的崩溃可能是之前发生的内存损坏的结果。
  • 在调试器中运行应该很容易调试。段错误发生在哪一行?正如其他人指出的那样,这些调用中的任何一个都可能失败,因为您从不检查返回值。例如,如果pModule == NULL,那么下一个获取属性的调用将会出错。
  • 另外,我不相信PyImport_Import 默认使用当前目录(我可能是错的)。如果是这样,那么如果不将当前目录添加到 PYTHONPATHmain.py 将无法导入。
  • 嗨,我用 GDB 一步一步开始了代码,pModule 返回 NULL。我试图通过在 Py_Initialize(); 行之后添加行 PySys_SetPath(L"."); 来解决此问题,但我遇到了同样的问题。

标签: python c cpython


【解决方案1】:

pArgs 必须是一个元组。在格式字符串中添加括号:

pArgs = Py_BuildValue("(s)",(char*)"Greg"); 

我没有收到分段错误,而是收到一条明确的错误消息,因此您可能也遇到了构建问题。

TypeError: argument list must be a tuple

【讨论】:

  • 您好,感谢您的帮助。我添加了括号,但仍然出现错误。我使用以下行编译我的程序:gcc -g -o test test.c -I/usr/include/python3.8 -lpython3.8。在那之后我没有任何警告或错误。
  • @Tears4fears 这对我来说看起来不错,但我在 Windows 上并使用 Microsoft 编译器,因此无法验证。添加一些错误检查或使用调试器查看崩溃的位置。使用"(s)" 后显示的代码对我有用。
  • @Tears4Fears Py_BuildValue 本身并没有太大的问题。该行的语法是正确的。您确定崩溃发生在该特定行上吗?
【解决方案2】:

正如你所说,我替换了pArgs = Py_BuildValue("s",(char*)"Greg");

pArgs = Py_BuildValue("(s)",(char *)"137912500");.

正如你所说,我在错误的目录中,所以我添加了PySys_SetPath(L".");

这是我更正后的 C 代码:

#include <stdio.h>
#include <Python.h>

void main(void) {
        Py_Initialize();
        PyObject *pName,*pName2, *pModule, *pFunc, *pArgs, *pValue;
        PySys_SetPath(L".");
        pName = PyUnicode_FromString((char*)"main");
        pModule = PyImport_Import(pName);
        pFunc = PyObject_GetAttrString(pModule, (char*)"main");
        pArgs = Py_BuildValue("(s)",(char *)"137912500");
        pValue = PyObject_CallObject(pFunc, pArgs);                  
        Py_Finalize();                                               
        return;
}

再次感谢您的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-01
    • 2014-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多