我在使用C API來找出正確的方式來回溯Python回溯時遇到了一些麻煩。我正在編寫嵌入Python解釋器的應用程序。我希望能夠執行任意Python代碼,並且如果它引發異常,請將其轉換爲我自己的特定於應用程序的C++異常。目前,僅提取Python異常引發的文件名和行號就足夠了。這是我到目前爲止有:從C API訪問Python回溯
PyObject* pyresult = PyObject_CallObject(someCallablePythonObject, someArgs);
if (!pyresult)
{
PyObject* excType, *excValue, *excTraceback;
PyErr_Fetch(&excType, &excValue, &excTraceback);
PyErr_NormalizeException(&excType, &excValue, &excTraceback);
PyTracebackObject* traceback = (PyTracebackObject*)traceback;
// Advance to the last frame (python puts the most-recent call at the end)
while (traceback->tb_next != NULL)
traceback = traceback->tb_next;
// At this point I have access to the line number via traceback->tb_lineno,
// but where do I get the file name from?
// ...
}
在Python源代碼挖的時候,我看到他們通過_frame
結構,它看起來既訪問當前幀的文件名和模塊名像是一個privately-定義的結構。我的下一個想法是以編程方式加載Python的'traceback'模塊並用C API調用它的函數。這是否理智?有沒有更好的方法來從C訪問Python追溯?
[PyErr_Fetch](https://docs.python.org/2/c-api/exceptions.html#c.PyErr_Fetch)產生內存泄漏(取決於實現它可能很重要) – alex
「PyTracebackObject * traceback =(PyTracebackObject *)traceback;」的目的是什麼?我認爲你的意思是「PyTracebackObject * traceback =(PyTracebackObject *)excTraceback;」。 – aquirdturtle