2010-02-10 232 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