pyeval_callobject 가끔 루프에서 실패합니다
-
19-09-2019 - |
문제
나는 Python C API와 약간 어려움을 겪고 있습니다. 약 60Hz에서 게임 AI를 수행하기 위해 파이썬 방법을 호출하고 있습니다. 효과가있다 대부분 시간이 지남에 따라 1 초마다 pyeval_callobject로 호출하면 널 리턴 값이 발생합니다. 오류를 올바르게 감지하고 계속 루핑하면 다음 초 정도가 잘되면 오류가 다시 발생합니다.
나는 심판 계산에 뭔가 잘못하고 있다고 생각하지만 그것이 무엇인지 알 수 없습니다.
int script_do_ai(struct game_data_t* gd)
{
PyObject *pAiModule, *pResult;
float result=0.0;
pResult = NULL;
pAiModule = PyImport_Import(PyString_FromString("ai_script"));
예, 반복마다 모듈을 가져오고 있습니다. 필요합니까? Paimodule을 글로벌로 저장하면 약 1 초 후에 충돌이 발생합니다.
pResult = PyEval_CallObject(PyObject_GetAttrString(pAiModule, "do_ai"),
Py_BuildValue("f", gd->important_float))
if (pResult != NULL)
{
PyArg_Parse(pResult, "f", &result);
Py_DECREF(pResult);
ConquerEnemies(result); //you get the idea
}
else //this happens every 75 or so iterations thru the loop
{
if (PyErr_ExceptionMatches(PyExc_SomeException)) //? not sure what to do here
{
테스트없이 아직 예외를 추출하는 방법을 찾을 수 없었습니다. 모든 예외
}
}
내가 이것을 제대로하는 것도 가깝습니까? 내가 말했듯이, 그것은 대부분 작동하지만 왜 내가 오류가 발생하는지 이해하고 싶습니다.
도움을 주셔서 감사합니다.
해결책
전화해도됩니다 PyImport_Import()
자주 원하는만큼 동일한 모듈 객체를 계속 얻을 수 있습니다. 파이썬 캐시 수입. 또한 새 Python 문자열을 만들고 참조 (및 객체)를 누출하는 대신 사용해야합니다. PyImport_ImportModule()
, 그것은 a const char *
.
PyImport_Import*()
그러나 새로운 참조를 반환하지만 전화해야합니다. Py_DECREF()
당신이 끝났을 때 그것에. 글로벌에 모듈을 저장하는 것은 문제가되지 않아야합니다.
당신의 전화에서 PyEval_CallObject()
당신은 결과를 확인하지 않습니다 Py_BuildValue()
오류에 대해서도 전화하지 않습니다 Py_DECREF()
당신이 그것을 끝내면, 당신은 그 물체도 새고 있습니다.
파이썬 플로트를 C 더블로 변환하려면 아마도 PyFloat_AsDouble()
멍청이 대신 PyArg_Parse()
(예외를 테스트하려면 명심하십시오)
실제 오류 처리까지 : PyErr_ExceptionMatches()
예외가 무언가와 일치하는지 실제로 테스트하려는 경우에만 유용합니다. 예외가 발생했는지 알고 싶거나 실제 예외 객체를 얻으려면 PyErr_Occurred()
당신이 전화해야 할 것입니다. 현재 예외를 반환합니다 유형 (실제 예외 객체가 아님) 빌린 참조 또는 설정이없는 경우 NULL. Stderr에 추적을 인쇄하려면 PyErr_Print()
그리고 PyErr_Clear()
사용하고 싶은 것입니다. 코드의 실제 오류를보다 세밀하게 검사하려면 PyErr_Fetch()
현재 예외 객체와 관련된 트레이스 백을 얻습니다 (동일한 정보를 얻을 수 있습니다. sys.exc_info()
Python Code에서.) 모든 것은 C 코드의 예외 처리에 대해 깊이 들어가기를 원하지 않습니다.