2011-05-25 70 views
1

我使用cython將python與C++庫進行接口。我需要一個C++代碼可以調用的回調函數。我還需要將對特定python對象的引用傳遞給此函數。這從回調演示中很清楚。Cython回調導致內存損壞/段錯誤

但是我得到的各種錯誤回調時從C++線程(並行線程)呼籲:

  1. 通函數指針和類/對象(爲void *)到C++
  2. 器C中的指針++
  3. 開始新的線程(並行線程),運行使用存儲的函數指針,並傳回類指針循環
    1. 呼叫功能(無效*)
  4. 在蟒:投無效*回類/對象
  5. 呼叫上述類/對象(錯誤)的方法

步驟2和3是在C++中。

這些錯誤大多是分段錯誤,但有時候我會抱怨一些低級別的python調用。

我有完全相同的代碼,我在python中創建一個線程,並直接調用回調。這工作正常。所以回調本身正在工作。

我確實需要一個獨立的線程運行在C++中,因爲這個線程正在與硬件進行通信,並且偶爾會調用我的回調函數。

我也三重檢查了所有正在傳遞的指針。他們指向有效的地點。

我懷疑從C++線程使用cython類時會出現一些問題..?

我在Ubuntu上使用Python 2.6.6。

所以我的問題是: 我可以從非python線程操縱python對象嗎? 如果沒有,有沒有辦法可以使線程python兼容? (並行線程)

這是已經導致當來自C++線程調用問題的最低迴調:

cdef int CheckCollision(float* Angles, void* user_data): 
    self = <CollisionDetector>user_data 
    return self.__sizeof__() # <====== Error 

回答

1
  1. 不,你不能沒有在第一時間獲取GIL操縱Python對象。您必須使用PyGILState_Ensure() + PyGILState_Release()(見PyGILState_Ensure documentation

  2. 可以確保你的對象將Python中不會被刪除,如果你明確地把參考,並釋放它,當你不使用它了與Py_INCREF()Py_DECREF() 。如果你將回調傳遞給你的C++,並且如果你沒有再使用引用,也許你的python對象被釋放,並且發生崩潰(參見Py_INCREF documentatation)。

Disclamer:我不是說這是你的問題,只是給你提示,以追查錯誤:)

+0

工作就像一個魅力,謝謝 – mithrandir123 2011-05-26 12:48:36