Python 程序在空闲状态下工作,但在命令行失败

Python 程序在空闲状态下工作,但在命令行失败,python,dll,ctypes,python-idle,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

我正在使用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>
Microsoft Windows[版本6.1.7601]
版权所有(c)2009微软公司。版权所有。
C:\Users\Admin>cd Desktop\code
C:\Users\Admin\Desktop\code>C:\Python27\python.exe test.py
当前目录:C:\Users\Admin\Desktop\code
sys.path:
C:\Users\Admin\Desktop\code
C:\Windows\system32\python27.zip
C:\Python27\dll
C:\Python27\lib
C:\Python27\lib\plat-win
C:\Python27\lib\lib-tk
C:\Python27
C:\Python27\lib\site包
打开相机。。。
相机手柄:43742176
正在设置传感器格式。。。
回溯(最近一次呼叫最后一次):
文件“test.py”,第18行,在
PCO_api.PCO_GetSensorFormat(摄像头_手柄,ctypes.byref(传感器))
文件“\u ctypes/callproc.c”,第936行,在GetResult中
WindowsError:[错误-1609945086]Windows错误0xA00A3002
C:\Users\Admin\Desktop\code>
请注意,一些DLL调用是有效的,直到我开始设置传感器格式,我们才偏离轨道

通过检查我调用的DLL附带的文档,我看到Windows错误解码为“缓冲区的大小太小了”(原文如此)。我不确定这是否相关。以防万一

当我看到“在空闲时工作,在提示时失败”时,我假设一定有一些环境变量设置不同。我应该检查什么

编辑:

我在测试代码中添加了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)均无效

编辑:


如果我将上面的代码输入到“香草”交互式python解释器中,它也可以工作。我不需要IDLE或ipython来让它工作。仅调用“python.exe test.py”失败。

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

您得到的错误使我相信您用于存储wSensor变量的16位整数太小。我查看了他们的API,它只是将其指定为WORD类型,按照Microsoft标准,历史上应该是16位,但由于单词的大小存在很多歧义,请尝试将该值增加到32或64位


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

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

有鉴于此,让我们看看下面这行:

PCO_api.PCO_OpenCamera(ctypes.byref(camera_handle), 0)
根据API文档,在上述调用中,
PCO_OpenCamera
函数不仅仅返回
camera_handle
中的值;它还使用
camera\u handle
作为输入值。但是,您将
camera\u值保持为未初始化状态。我知道你应该在通话前把它设为零。另一个问题是,
PCO\u OpenCamera
返回一个应该检查的值。如果有问题,但程序继续运行,就好像没有问题一样,它将继续为
摄像头\u手柄使用随机值。因此,程序中的一个错误似乎是前一行(保存打印)应该是

camera_handle = ctypes.c_ulong(0)
另一个原因是没有检查
PCO\u OpenCamera
的返回值。(我不知道其他的是否合适,我没有仔细检查过。)


另外,
c_ulong
是否是Windows
HANDLE
类型的合适类型?我不知道,也许还可以。即使
c_ulong
大于
HANDLE
,它也可能是正常的。但可能还不够;你必须确定你知道自己在做什么。

检查空闲执行和命令行执行中的
os.getcwd()
sys.path
。好建议,Joel Cornett。我已经按照你的建议修改了这个问题。windows上的Cpython是否仍然具有
wpython.exe
vs
python.exe
的区别?如果是这样,请尝试
wpython.exe test.py
。@Francis:你的意思是
pythonw.exe
?@Francis我尝试了pythonw.exe而不是python.exe。很难判断发生了什么,因为终端上没有打印任何内容。我相信它仍然会崩溃,用pythonw.exe代替python.exe。我在上面的脚本末尾添加了
import time
time.sleep(10)
,并在任务管理器中观察了pythonw.exe进程。该过程不会持续10秒,除非我注释掉导致python.exe崩溃的行。好问题。我想我可以用
sys.executable
来检查这一点。在空闲状态下,
sys.executable
C:\Python27\pythonw.exe
,测试脚本可以工作。在Ipython中,
sys.executable
C:\Python27\python.exe