2

博士号取得のために高速カメラからのデータを処理するプログラムを作成しています。事業。このカメラには、カメラと通信して画像を取得するための、Linux 上の .so ファイル形式の SDK が付属しています。前述のように、大量のデータを配信する高速カメラです (1 分間に数 GB)。この量のデータを処理するために、SDK には非常に便利なスプール機能があり、データを DMA 経由でハード ドライブに直接スプールします。FITS ファイルは、天文学で使用されるヘッダー付きの生のバイナリ形式です。この関数は、小さな C プログラムを作成し、.so ファイルをリンクして、この方法でスプール関数を呼び出すと正常に機能します。しかし、.so ファイルを ctypes でラップして Python から関数を呼び出すと、スプール関数を除くすべての関数が動作します。スプール関数を呼び出すと、エラーは返されませんが、スプールされたデータ ファイルが文字化けします。ファイルの形式は正しいのですが、全フレームの半分が 0 です。私の世界では、.so ファイル内の関数が、自分の小さな C プログラムまたは python から呼び出されたプログラムに応じて異なる動作をする必要があることは意味がありません。さまざまなプログラムから .so を呼び出すときの違いについて、何か手がかりはありますか?

私はどんな提案にもとても感謝しています

カメラは商用ですが、一部のドライバーは GPL 化されて利用可能ですが、少し複雑です。(残念ながら、スプール機能ではないようです)カメラのヘンデル用のPythonのオブジェクトがあります。

クラスの冒頭には次のように書かれています。

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()
4

1 に答える 1

0

私の推測では、それはスプーリング関数自体の呼び出しではなく、ライブラリとの間で破損した値が供給される一連の呼び出しであると考えられます。

64 ビット プラットフォームを使用していますか? restype64 ビット整数 ( longgcc を使用) またはポインターを返すものを指定しないと、これらの値は黙って 32 ビットに切り捨てられます。さらに、ctypes.c_voidp処理は少し驚くべきものです —restypeの値はctypes.c_voidp切り捨てられませんが、Python インタープリターでは type としてint返されます。ハイ ポインターがキャストせずに他の関数にパラメーターとしてフィードバックされると、予想通り面白い結果になります。

私はそれをテストしていませんが、これらの条件は両方とも、sys.maxint より大きい値の 32 ビット プラットフォームにも影響を与える可能性があります。

期待する値を渡したり受け取ったりしていることを 100% 確実にする唯一の方法は、呼び出すすべての関数に対してargtypesandを指定することです。これには、関数が操作するすべての s (不透明な s も含む) のクラスと関連するs のrestype作成が含まれます。StructurePOINTERstructstruct

于 2010-09-02T18:38:59.600 に答える