从SWIG包装的C ++函数中获取当前的Python调用堆栈

Obtain current Python call stack from within SWIG wrapped C++ function

如果我从Python调用SWIG包装的C / C ++函数,是否有可能获得当前的调用堆栈? 我想要类似于''.join(traceback.format_stack())的结果,但我不想将它从Python传递给我的C / C ++函数,因为我并不总是需要它。 因此,如果我的C / C ++方面出现错误,我想在运行中获取并打印它。


我在这篇文章之后想出了一个解决方案,虽然如果有的话,我仍然更喜欢更自然的方法来获得相同的东西。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// This is similar to the python code:
//   def GetScriptingLanguageCallStack():
//     import traceback
//     return ''.join(traceback.format_stack())
string GetScriptingLanguageCallStack() {
  string result;

  PyObject* module_name = PyString_FromString("traceback");
  PyObject* pyth_module = PyImport_Import(module_name);
  Py_DECREF(module_name);

  if (pyth_module != nullptr) {
    PyObject* pyth_func = PyObject_GetAttrString(pyth_module,"format_stack");
    if (pyth_func != nullptr) {
      if (PyCallable_Check(pyth_func)) {
        PyObject* pyth_val = PyObject_CallFunctionObjArgs(pyth_func, 0);
        if (pyth_val != nullptr) {
          if (PyList_Check(pyth_val)) {
            const int size = PyList_GET_SIZE(pyth_val);
            for (int i = 0; i < size; ++i) {
              PyObject* pyth_line = PyList_GET_ITEM(pyth_val, i);
              result += PyString_AsString(pyth_line);
            }
          }
          Py_DECREF(pyth_val);
        }
      }
      Py_DECREF(pyth_func);
    }
    Py_DECREF(pyth_module);
  }
  return result;
}

顺便说一句,我不喜欢使用框架对象的链接帖子中的方法,因为给定的行号不是指向进行进一步函数调用的确切行,而是仅指向包含函数名称的行。