2010-05-21 53 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。