程序在IDLE中工作,但在命令行失败

时间:2012-05-09 22:57:25

标签: python dll ctypes python-idle

我正在使用Python的ctypes库与Windows DLL进行通信。当我从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很小”。 (原文如此)。我不确定这是否相关。万一重要,here's the API documentation

当我看到“在IDLE中工作,在提示时失败”时,我认为必须设置一些不同的环境变量。我该怎么检查?

编辑:

我将sys.path和os.getcwd()添加到测试代码中。

编辑:

不确定这是否重要,但我加载的DLL(SC2_Cam.dll)位于当前工作目录中。此目录中还有另一个DLL(sc2_cl_me4.dll),我相信它是由SC2_Cam.dll加载的。如果我从此目录中删除sc2_cl_me4.dll,则无法调用SC2_Cam.dll,包括PCO_OpenCamera。

编辑:

如果我将它输入'vanilla'交互式python解释器,上面的代码也可以工作。我不需要IDLE或ipython来使它工作。只调用'python.exe test.py'失败。

3 个答案:

答案 0 :(得分:5)

您的系统上安装了多个版本的python吗?当您以交互方式运行以及从文件运行时,可能正在使用不同的版本。

答案 1 :(得分:4)

当你与C程序接口时,你会遇到C的所有困难。你所做的任何错误都可能导致缓冲区溢出,堆栈溢出,分段违规等。如果程序由于错误而写入随机存储器位置,它的行为在所有情况下都不一样。在您的计算机上,它似乎在交互模式下工作,但从窗口命令提示符运行时崩溃。但是在另一个操作系统上,或在另一台机器上,或者在另一天的同一台机器上,它可能表现不同。它的行为不确定。

鉴于此,让我们看看以下一行:

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

根据API文档,在上面的调用中,PCO_OpenCamera函数不只返回camera_handle中的值;它还使用camera_handle作为输入值。但是,您将camera_value保留为未初始化状态。我知道你应该在通话前将它设置为零。另一个问题是PCO_OpenCamera返回一个应该检查的值。如果出现问题但程序仍然继续,就好像没有,它将继续使用camera_handle的随机值。因此,程序中的一个错误似乎是前一行(保存打印)应为

camera_handle = ctypes.c_ulong(0)

另一个是不检查PCO_OpenCamera的返回值。 (我不知道其余的是否合适,我没有仔细检查过。)

此外,c_ulongHANDLE类型的正确类型吗?我不知道,也没关系。即使c_ulong大于HANDLE,它仍然可能确定。但可能还不够;你必须确定你知道自己在做什么。

答案 2 :(得分:1)

你得到的错误让我相信你用来存储wSensor变量的16位整数太小了。我查看了他们的API,它只是将其指定为WORD类型,历史上微软标准应该是16位,但由于关于字的大小有很多歧义,请尝试将值增加到32或64位。 / p>

至于为什么这会导致不同环境中的不同行为,您使用的是64位操作系统吗?你有不同版本的python安装吗?