C ++ /嵌入式Python:从Python调用C ++函数时,能否检索Python文件名和行号

问题描述

我使用PyRun_SimpleFile从C ++程序运行Python脚本。我定义了一个自定义模块(使用PyImport_AppendInittabas done here),因此可以在我的Python脚本中导入它,并且当使用来自该模块的函数时,Python脚本可以执行一些C ++代码通过Python解释器调用的回调PyObject* MyFunction(PyObject *self,PyObject *args)

我想知道正在调用的回调函数中的当前脚本文件名和行号。

我找不到任何方法来检索它。这可能吗?

注意:此问题绝对不是How to get the caller's method name in the called method?的重复。我正在尝试从正在执行的C ++代码中检索文件名和行号,然后再由Python脚本执行。

解决方法

您将需要PyTraceBack_Here

您可以看一下追溯对象的实现here

以下是由PyTraceBack_Here

创建的回溯示例printig
#include <Python.h>

PyObject * mymodule_meth_test(PyObject * self) {
    PyTraceBack_Here(PyEval_GetFrame());
    PyObject * exc;
    PyObject * val;
    PyObject * tb;
    PyErr_Fetch(&exc,&val,&tb);
    PyTraceBack_Print(tb,PySys_GetObject("stderr"));
    Py_RETURN_NONE;
}

PyMethodDef module_methods[] = {
    {"test",(PyCFunction)mymodule_meth_test,METH_NOARGS,NULL},{},};

PyModuleDef module_def = {PyModuleDef_HEAD_INIT,"mymodule",NULL,-1,module_methods};

extern "C" PyObject * PyInit_mymodule() {
    PyObject * module = PyModule_Create(&module_def);
    return module;
}

您应该能够从tb对象中提取文件名和行号。 这是一个普通的PyObject,您可以将其传递给python脚本或对其进行检查。

以下是在不考虑引用计数的情况下提取值的方法:

    int line = PyLong_AsLong(PyObject_GetAttrString(PyObject_GetAttrString(tb,"tb_frame"),"f_lineno"));
    const char * filename = PyUnicode_AsUTF8(PyObject_GetAttrString(PyObject_GetAttrString(PyObject_GetAttrString(tb,"f_code"),"co_filename"));

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...