2010-02-10 60 views
2

我在Python C API中挣扎了一番。我正在调用python方法在60Hz左右做一些AI游戏。它的工作原理是,大部分是,但是每隔一秒左右,对PyEval_CallObject的调用就会产生一个NULL返回值。如果我正确地检测到错误并继续循环,那么在接下来的一秒左右时间内都会很好,因此错误再次出现。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作为全球存储,大约一秒钟后我会发生严重故障。

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 
     { 

我一直无法找出如何提取例外的是,无论是...没有测试例外

 } 
    } 

难道我甚至接近这样做对吗?就像我说的那样,它大部分都可以工作,但我真的很想理解为什么我会遇到错误。

非常感谢您的帮助。

回答

4

您可以随时拨打PyImport_Import(),但您只会继续收到相同的模块对象。 Python缓存导入。另外,不要创建一个新的Python字符串,并且泄漏参考文件(因此也就是对象),您应该只使用PyImport_ImportModule(),它需要const char *

PyImport_Import*()返回一个新的参考,但是,你应该在完成后调用Py_DECREF()。将模块存储在全局中应该不成问题,只要您拥有对其的引用即可(您在此执行此操作)。

在您致电PyEval_CallObject()时,您不检查Py_BuildValue()的结果是否有错误,当你完成它时,你也不会调用Py_DECREF(),所以你也泄漏了这个对象。

为了转换一个Python浮到C双键的,你应该只调用PyFloat_AsDouble(),而不是摆弄PyArg_Parse()(并牢记测试例外)

下到实际的错误处理:PyErr_ExceptionMatches()只有当你真的想测试异常是否匹配时才有用。如果您想知道是否发生异常,或者获取实际的异常对象,则应该调用PyErr_Occurred()。它将类型的当前异常(不是实际的异常对象)作为借用引用返回,如果没有设置,则返回NULL。如果您只想打印回溯到stderr,则需要使用PyErr_Print()PyErr_Clear()。为了更细粒度地检查代码中的实际错误,PyErr_Fetch()会为您提供当前的异常对象以及与其相关的跟踪信息(它将为您提供与Python代码中的sys.exc_info()相同的信息。)所有您认为很少想要获得的信息深入到C代码中的异常处理。

+0

+1谢谢...我想如果我内联Py_BuildValue的调用,它会照顾泄漏的引用,但也许不会。 我会看到PyErr_Fetch在pyErr_Occurred上给我什么 – 2010-02-10 05:22:42

+0

唉,C不是垃圾回收:) PyErr_Print()对于打印异常非常方便,特别是在调试像这样的情况下。 – 2010-02-10 05:24:04

+0

对于我而言,.NET环境下的时间太长了。 好吧奇怪。我添加了“sys.stdout = open('CONOUT $','wt')”到我的python脚本(输出到控制台...我在Win32中),一切都开始神奇地工作。离奇。 – 2010-02-10 05:34:25