Python C++;API:如何检索NameError的lineno属性

Python C++;API:如何检索NameError的lineno属性,python,c++,c,api,Python,C++,C,Api,我正在使用用于C/C++的python API,我想检索 发生名称错误时的行号 我遵循了以下问题中的说明: 我编写了以下代码: PyObject*ptype=NULL,*pvalue=NULL,*ptraceback=NULL; PyObject*comp=NULL,*eval=NULL; 字符代码[]={“A=undef_var”}; comp=Py_编译器字符串(代码,“,Py_文件输入); 如果(公司){ eval=PyEval\u EvalCode(comp,PyEval\u Get

我正在使用用于C/C++的python API,我想检索 发生名称错误时的行号

我遵循了以下问题中的说明:

我编写了以下代码:

PyObject*ptype=NULL,*pvalue=NULL,*ptraceback=NULL;
PyObject*comp=NULL,*eval=NULL;
字符代码[]={“A=undef_var”};
comp=Py_编译器字符串(代码,“,Py_文件输入);
如果(公司){
eval=PyEval\u EvalCode(comp,PyEval\u GetBuiltins(),NULL);
}
如果(!comp | |!eval){
PyErr_PrintEx(1);//在这个函数中调用PyErr_Fetch(ptype、pvalue、ptraceback)
//检索从PyErr_PrintEx(1)内部调用的PyErr_Fetch()获取的信息
pvalue=PySys_GetObject(“最后一个值”);
ptype=PySys_GetObject(“last_type”);
ptraceback=PySys_GetObject(“最后一次回溯”);
PyErr_规范化异常(ptype、pvalue、ptraceback);
PyObject*line_no=PyObject_GetAttrString(pvalue,“lineno”);
如果(行号){
PyObject*line_no_str=PyObject_str(line_no);
PyObject*line_no_unicode=PyUnicode_AsEncodedString(line_no_str,“utf-8”,“Error”);
char*actual\u line\u no=PyBytes\u AsString(line\u no\u unicode);
}
}
上面的代码返回正确的行号,以防python代码 包含语法错误(例如,对于简单的python代码,如“a=”), 但是,如果出现NameError,行号没有正确设置为pvalue对象(例如,对于python代码:“a=undefined_var”)


有什么办法可以解决这个问题吗?

在@Antti Haapala的帮助下,考虑到发布在本文中的解决方案,我得出以下结论:

PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL;
PyObject *compile_obj = NULL, *eval_obj = NULL;
PyObject *line_no = NULL, *line_no_str = NULL, *line_no_unicode = NULL;
char *actual_line_no = NULL;
char code[] = { "A=undef_var" };
int line_num = 0;

compile_obj = Py_CompileString(code, "", Py_file_input);
if (compile_obj) {
    eval_obj = PyImport_ExecCodeModule((char *)"", compile_obj);
}
if (!compile_obj || !eval_obj) {
    PyErr_PrintEx(1); // inside this function the PyErr_Fetch(ptype, pvalue, ptraceback) is called
                      // retrieve the information gained from PyErr_Fetch() called inside PyErr_PrintEx(1) 
    pvalue     = PySys_GetObject("last_value");
    ptype      = PySys_GetObject("last_type");
    ptraceback = PySys_GetObject("last_traceback");
    if (ptype) {
        PyErr_NormalizeException(&ptype, &pvalue, &ptraceback);
    }
    if (compile_obj) { // NameError
        if (ptraceback) {
            PyTracebackObject *tb_o = (PyTracebackObject *)ptraceback;
            line_num = tb_o->tb_lineno;
        }
    } else { //Syntax Error
        line_no = PyObject_GetAttrString(pvalue, "lineno");
        if (line_no) {
            line_no_str = PyObject_Str(line_no);
            if (line_no_str)     line_no_unicode = PyUnicode_AsEncodedString(line_no_str, "utf-8", "Error");
            if (line_no_unicode) actual_line_no = PyBytes_AsString(line_no_unicode);
            if (actual_line_no)  line_num = atoi(actual_line_no);

            Py_XDECREF(line_no);
            Py_XDECREF(line_no_str);
            Py_XDECREF(line_no_unicode);
        }
    }
}
Py_XDECREF(compile_obj);
Py_XDECREF(eval_obj);

return line_num;

你就不能用boost库来做这个吗?然后你可以查看这个stackoverflow链接:不幸的是,我不能使用boost库。谢谢你的回答!请注意,您必须单独检查每个
Py.*
函数的返回值,并相应地执行操作。您会注意到
namererror
甚至没有属性
lineno
。如果您操作正确,您应该知道
namererror
没有属性
lineno
,这就是它不起作用的原因。您需要访问该代码,因为您在该代码中至少缺少8个返回值检查-此外,您在这里有几个漏洞。此外,您只是假设返回值。