6

Pythonのctypesライブラリを使用してWindowsDLLと通信しています。IDLE、Ipythonからコードを実行するか、インタラクティブなpythonインタープリターに入力すると、正常に機能します。Windowsのコマンドプロンプトから同じコードを実行すると、クラッシュします。なぜ一方向がクラッシュし、一方向が成功するのですか?

これが私が実行しているコードの簡略化されたバージョンです:

import ctypes, os, sys

print "Current directory:", os.getcwd()
print "sys.path:"
for i in sys.path:
    print i

PCO_api = ctypes.oledll.LoadLibrary("SC2_Cam")

camera_handle = ctypes.c_ulong()
print "Opening camera..."
PCO_api.PCO_OpenCamera(ctypes.byref(camera_handle), 0)
print " Camera handle:", camera_handle.value

wSensor = ctypes.c_uint16(0)
print "Setting sensor format..."
PCO_api.PCO_SetSensorFormat(camera_handle, wSensor)
PCO_api.PCO_GetSensorFormat(camera_handle, ctypes.byref(wSensor))
mode_names = {0: "standard", 1:"extended"}
print " Sensor format is", mode_names[wSensor.value]

IDLEまたはIpythonからこのコードを実行すると、次の結果が得られます。

Current directory: C:\Users\Admin\Desktop\code
sys.path:
C:\Users\Admin\Desktop\code
C:\Python27\Lib\idlelib
C:\Windows\system32\python27.zip
C:\Python27\DLLs
C:\Python27\lib
C:\Python27\lib\plat-win
C:\Python27\lib\lib-tk
C:\Python27
C:\Python27\lib\site-packages
Opening camera...
 Camera handle: 39354336
Setting sensor format...
 Sensor format is standard
>>> 

Windowsコマンドプロンプトからこのコードを実行すると、次の結果が得られます。

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\Admin>cd Desktop\code

C:\Users\Admin\Desktop\code>C:\Python27\python.exe test.py
Current directory: C:\Users\Admin\Desktop\code
sys.path:
C:\Users\Admin\Desktop\code
C:\Windows\system32\python27.zip
C:\Python27\DLLs
C:\Python27\lib
C:\Python27\lib\plat-win
C:\Python27\lib\lib-tk
C:\Python27
C:\Python27\lib\site-packages
Opening camera...
 Camera handle: 43742176
Setting sensor format...
Traceback (most recent call last):
  File "test.py", line 18, in <module>
    PCO_api.PCO_GetSensorFormat(camera_handle, ctypes.byref(wSensor))
  File "_ctypes/callproc.c", line 936, in GetResult
WindowsError: [Error -1609945086] Windows Error 0xA00A3002

C:\Users\Admin\Desktop\code>

いくつかのDLL呼び出しが機能することに注意してください。センサー形式の設定に取り掛かるまで、レールから外れます。

呼び出しているDLLに付属のドキュメントを調べると、Windowsエラーが「バッファのwSizeが小さすぎます」とデコードされていることがわかります。(原文ママ)。それが適切かどうかはわかりません。重要な場合に備えて、ここにAPIドキュメントがあります

「IDLEで動作し、プロンプトで失敗する」と表示された場合、環境変数が別の方法で設定されている必要があると思います。何を確認すればよいですか?

編集:

テストコードにsys.pathとos.getcwd()を追加しました。

編集:

これが重要かどうかはわかりませんが、ロードしたDLL(SC2_Cam.dll)は現在の作業ディレクトリにあります。また、このディレクトリには別のDLL(sc2_cl_me4.dll)があり、SC2_Cam.dllによってロードされていると思います。このディレクトリからsc2_cl_me4.dllを削除すると、PCO_OpenCameraを含め、SC2_Cam.dllへの呼び出しは機能しません。

編集:

上記のコードは、「バニラ」インタラクティブPythonインタープリターに入力した場合にも機能します。IDLEやipythonを機能させる必要はありません。'python.exetest.py'の呼び出しのみが失敗します。

4

3 に答える 3

5

システムに複数のバージョンのPythonがインストールされていますか?インタラクティブに実行する場合とファイルから実行する場合は、おそらく異なるバージョンを使用しています。

于 2012-05-13T02:15:37.120 に答える
4

Cプログラムとインターフェイスすると、Cのすべての問題が発生します。エラーが発生すると、バッファオーバーフロー、スタックオーバーフロー、セグメンテーション違反などが発生する可能性があります。プログラムがエラーのためにランダムなメモリ位置に書き込む場合、動作はすべての状況で同じになるわけではありません。お使いのマシンでは、インタラクティブモードで動作しているように見えますが、ウィンドウコマンドプロンプトから実行するとクラッシュします。ただし、別のオペレーティングシステム、別のマシン、または別の日の同じマシンでも、動作が異なる可能性があります。その動作は決定論的ではありません。

それを踏まえて、次の行を見てみましょう。

PCO_api.PCO_OpenCamera(ctypes.byref(camera_handle), 0)

APIドキュメントによると、上記の呼び出しでは、関数は;PCO_OpenCameraの値を返すだけではありません。入力値としてcamera_handleも使用します。camera_handleただし、初期化しないままにしておきますcamera_value。電話をかける前にゼロに設定する必要があることを理解しています。もう1つの問題は、PCO_OpenCameraチェックする必要のある値を返すことです。問題があるが、プログラムが問題がなかったかのように続行する場合、プログラムは引き続きランダムな値を使用しますcamera_handle。したがって、プログラムの1つのエラーは、前の行(印刷物を保存する)が

camera_handle = ctypes.c_ulong(0)

もう1つは、の戻り値がPCO_OpenCameraチェックされないことです。(残りが大丈夫かどうかはわかりませんが、それ以降は慎重に調べていません。)

また、c_ulongWindowsタイプに適したHANDLEタイプですか?わかりませんが、大丈夫かもしれません。c_ulongより大きい場合でもHANDLEおそらく問題ありません。しかし、おそらく十分ではありません。あなたは自分が何をしているのかを知っていることを確信しなければなりません。

于 2012-05-15T15:43:37.250 に答える
1

発生しているエラーにより、wSensor変数の格納に使用している16ビット整数が小さすぎると思われます。私は彼らのAPIを調べました。これは、タイプWORDとして指定されています。これは歴史的にMicrosoftの標準では16ビットであるはずですが、単語の大きさには多くのあいまいさがありますので、値を32ビットまたは64ビットに上げてみてください。

これが異なる環境で異なる動作を引き起こす理由について、64ビットOSを使用していますか?別のバージョンのPythonがインストールされていますか?

于 2012-05-13T02:36:13.057 に答える