2010-05-21 60 views
2

我正在寫一個程序來處理我的博士學位高速攝像機的數據。項目。該相機在Linux上以一個.so文件的形式提供SDK,用於與相機進行通信並獲取圖像。據說這是一臺高速攝像機,可以傳輸大量數據(每分鐘幾GB)。爲了處理這些數據,SDK具有非常方便的後臺處理功能,可以通過DMA將數據直接後臺處理到硬盤上,其格式爲FITS文件,這是一種帶有用於天文學標題的原始二進制格式。 當我編寫一個小型C程序時,該函數可以正常工作,鏈接.so文件並以這種方式調用spool函數。但是當我使用ctypes包裝.so文件並從python調用函數時,除了spool函數外,所有函數都正常工作。當我調用spool函數時,它不返回錯誤,但假脫機數據文件出現亂碼,文件格式正確,但所有幀的一半都爲0。 在我的世界裏,.so文件中的函數應該有不同的表現,這取決於它調用哪個程序,我自己的小C程序或python,畢竟這只是一個更大的C程序。從不同的程序調用.so時,任何機構是否有任何線索?當從.so文件與python中的ctypes鏈接時奇怪的改變行爲

,我會很感激的任何建議

即使相機是商業,有些司機是GPL的和可用的,雖然有點複雜。 (不幸的是不是它看起來的假脫機函數)我有一個Python的Handel對象的對象。

類的開頭寫道:

class Andor: 
    def __init__(self,handle=100): 
    #cdll.LoadLibrary("/usr/local/lib/libandor.so") 
    self.dll = CDLL("/usr/local/lib/libandor.so") 
error = self.dll.SetCurrentCamera(c_long(handle)) 
    error = self.dll.Initialize("/usr/local/etc/andor/") 

    cw = c_int() 
    ch = c_int() 
    self.dll.GetDetector(byref(cw), byref(ch)) 

相關函數讀取:

def SetSpool(self, active, method, path, framebuffersize): 
    error = self.dll.SetSpool(active, method, c_char_p(path), framebuffersize) 
    self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name) 
    return ERROR_CODE[error] 

而且在相應的標題它讀取:

unsigned int SetSingleTrackHBin(int bin); 

unsigned int SetSpool(int active, int method, char * path, int framebuffersize); 

unsigned int SetStorageMode(at_32 mode); 

unsigned int SetTemperature(int temperature); 

的代碼來獲取相機運行會讀取類似於:

cam = andor.Andor() 
cam.SetReadMode(4) 
cam.SetFrameTransferMode(1) 
cam.SetShutter(0,1,0,0) 
cam.SetSpool(1,5,'/tmp/test.fits',10); 
cam.GetStatus() 
if cam.status == 'DRV_IDLE': 
acquireEvent.clear() 
cam.SetAcquisitionMode(3) 
cam.SetExposureTime(0.0) 
cam.SetNumberKinetics(exposureNumber) 
cam.StartAcquisition() 
+1

你確定你在'ctypes'代碼中正確設置了'argtypes'和'restype'屬性嗎?如果你能向我們展示你的代碼和相關的C頭文件,那可能會有所幫助。 – 2010-05-21 15:18:29

+0

這個庫可能會以一種不會在純C構建中暴露出來的方式(或者在另一個未經過測試的編譯器/平臺上)發佈。這聽起來像你被一個不透明的共享對象卡住了,你可能只想用C包裝這個函數並對它進行子處理。您的包裝中也可能存在一個錯誤,但我們知道這絕不會發生;) – msw 2010-05-21 15:19:49

+0

我已經在代碼中添加了更多細節,關於子處理它的問題是,驅動器還負責冷卻相機等。所以我必須保持它的加載,並且據我所見,我只能從加載它的進程向它發送命令。我使用python代碼中的multiprocessing模塊來分離攝像機的操作,這個模塊可以通過C類型連接代碼來玩弄技巧。 – 2010-05-21 16:05:22

回答

0

我的猜測是,它不是對假脫機函數本身的調用,而是一個調用序列,導致將錯誤的值送入庫中。

您是否在64位平臺上?對於任何返回64位整數(帶有gcc的long)或指針的任何內容,都不會指定restype將導致這些值被無提地截斷爲32位。此外,ctypes.c_voidp處理有點令人驚訝 - ctypes.c_voidp的值不會被截斷,但會在Python解釋器中返回爲int類型,如果高指針作爲參數反饋給其他函數而不進行強制轉換,則會產生可預測的熱鬧結果。

我還沒有測試過,但這兩個條件可能也會影響32位平臺的值大於sys.maxint。

確保您傳遞和接收您期望的值的唯一方法是爲您調用的所有函數指定argtypesrestype。這包括爲所有struct創建Structure類和相關的POINTER s,這些功能操作在上,甚至不透明struct s。