PyEval_CallObject偶尔在循环中失败

2024-04-19 06:45:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我在使用pythoncapi时有点困难。我正在调用一个python方法来做一些游戏AI,频率大约为60hz。每次调用的值时都会返回NULL。如果我正确地检测到错误并继续循环,下一秒左右一切正常,然后错误再次发生。在

我怀疑我在裁判计数上做错了什么,但我不知道是什么:

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存储为全局,大约一秒钟后就会发生严重崩溃。在

^{pr2}$

我还没能找到如何提取异常…如果不测试每个异常

       }
    }

我差点就要这么做了吗?就像我说的,它基本上是有效的,但我真的想知道为什么我会出错。在

提前谢谢你的帮助。在


Tags: 方法游戏错误scriptdonullstructai
1条回答
网友
1楼 · 发布于 2024-04-19 06:45:11

您可以随意调用PyImport_Import(),但您将继续获取相同的模块对象。Python缓存导入。另外,您不应该创建一个新的Python字符串并泄漏引用(以及对象),而应该使用PyImport_ImportModule(),它接受一个const char *。在

PyImport_Import*()返回一个新的引用,完成后应该对其调用Py_DECREF()。在全局中存储模块应该不是问题,只要您拥有对它的引用(在这里就是这样做的)

在对PyEval_CallObject()的调用中,您没有检查Py_BuildValue()的结果是否有错误,并且在完成后也没有调用Py_DECREF(),因此也泄漏了该对象。在

为了将Python float转换为C double,您可能应该只调用PyFloat_AsDouble(),而不是使用PyArg_Parse()来胡闹(记住要测试异常)

具体到实际的错误处理:PyErr_ExceptionMatches()只有在您真正想要测试异常是否匹配时才有用。如果您想知道是否发生了异常,或者想获得实际的异常对象,PyErr_Occurred()是您应该调用的。它返回当前异常类型(不是实际的异常对象)作为借用引用,如果没有设置,则返回NULL。如果您只想打印到stderr的回溯,PyErr_Print()和{}是您想要使用的。为了更细致地检查代码中的实际错误,PyErr_Fetch()将为您提供当前异常对象及其关联的回溯(它将为您提供与Python代码中的sys.exc_info()相同的信息)。考虑到这些因素,您很少希望深入了解C代码中的异常处理。在

相关问题 更多 >