Sto riscontrando qualche problema nel trovare il modo corretto di eseguire un traceback Python utilizzando l'API C. Sto scrivendo un'applicazione che incorpora l'interprete Python. Voglio essere in grado di eseguire codice Python arbitrario e, se solleva un'eccezione, di tradurlo nella mia specifica eccezione C++ specifica per l'applicazione. Per ora, è sufficiente estrarre solo il nome del file e il numero di riga in cui è stata sollevata l'eccezione Python. Questo è quello che ho finora:Accesso a un traceback Python dall'API C
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?
// ...
}
scavare intorno nel codice sorgente Python, vedo accedono sia il nome file e modulo nome del frame corrente attraverso la struttura _frame
, che sembra che è un privately- struct definito. La mia prossima idea era caricare a livello di codice il modulo 'traceback' di Python e chiamare le sue funzioni con l'API C. È sano di mente? C'è un modo migliore per accedere a un traceback Python da C?
[PyErr_Fetch] (https://docs.python.org/2/c-api/exceptions.html#c.PyErr_Fetch) produce perdita di memoria (a seconda del l'implementazione può essere importante) – alex
Qual è lo scopo del traceback "PyTracebackObject * traceback = (PyTracebackObject *)"? Penso che tu intenda "PyTracebackObject * traceback = (PyTracebackObject *) excTraceback;". – aquirdturtle