我在使用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}$我还没能找到如何提取异常…如果不测试每个异常
}
}
我差点就要这么做了吗?就像我说的,它基本上是有效的,但我真的想知道为什么我会出错。在
提前谢谢你的帮助。在
您可以随意调用
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代码中的异常处理。在相关问题 更多 >
编程相关推荐