2013-07-24 85 views
4

爲了將它放到上下文中,我正在爲C DLL創建一個包裝器 - 相當複雜的用例,但請堅持下去!Python Ctypes&Threading

在我的包裝類的初始化過程中,我爲我的C DLL的函數創建了別名,以便我的類可以稍後輕鬆訪問它們。我做的另外一個任務是將一個回調函數傳遞給我的類中的一個函數到我的DLL中,該函數保存在一個靜態變量中並在以後使用。

最後,我產生了另一個線程,它重複調用我的DLL中的一個函數,它在執行中的某些工作和不同點上需要使用在我的類的init階段中分配的回調來調用Python程序。

當回調以這種方式被調用我收到以下:

WindowsError: exception: access violation reading 0x00000001 

我懷疑這是做穿線,因爲當我在同一個線程測試回調,我賦予它的DLL可以成功地調用它,並且所有的參數都傳遞給Python。是否有一些保護措施是通過我的DLL中的變量強制執行的,我使用它來保持我的回調?

+4

保留對Python方面的回調的引用,例如將其分配給全局。 – jfs

+0

什麼,仍然繼續做我在做什麼? –

+2

看看回調的'_objects'屬性。它保留了一個['CThunkObject'](http://hg.python.org/cpython/file/ab05e7dd2788/Modules/_ctypes/ctypes.h#l96)的引用,該引用具有'pcl_exec' C函數,標誌,轉換器,restype和Python可調用。不要讓垃圾收集,否則你會得到一個訪問衝突(ctypes'方便'處理Windows SEH異常...希望你只是記錄它,讓這個過程死掉)。 – eryksun

回答

2

從Python文檔上的ctypes:

的回調函數的重要注意事項:

請務必保持引用,只要它們是由C語言中使用CFUNCTYPE對象。 ctypes不會,如果你不這樣做,它們可能會被垃圾收集,在回調時崩潰你的程序。

如果您看到「訪問違規」或「分段錯誤」,並且您正在處理回調,那很可能是原因。正如J.F.塞巴斯蒂安所說,全局變量是一種選擇,儘管我通常在我的課程中保留了對主動回調的引用列表。

當不涉及回調時,請仔細檢查包裝中的類型。聲明一個錯誤的類型會變得很難看,而且很難弄清楚。