程序在IDLE中工作,但在命令行失败 [英] Program works in IDLE, but fails at the command line

查看:327
本文介绍了程序在IDLE中工作,但在命令行失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Python的ctypes库与Windows DLL进行通信。当我运行我的代码从IDLE,Ipython,或键入交互式python解释器,它的工作正常。当我从Windows命令提示符运行相同的代码时,它会崩溃。

I'm using Python's ctypes library to talk to a Windows DLL. When I run my code from IDLE, Ipython, or typed into the interactive python interpreter, it works fine. When I run the same code from the Windows command prompt, it crashes. Why does one way crash, and one way succeed?

以下是我正在运行的代码的简化版本:

Here's a simplified version of the code I'm running:

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运行此代码时,我得到以下结果:

When I run this code from IDLE or Ipython, I get the following result:

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命令提示符运行此代码时,我得到以下结果:

When I run this code from the Windows command prompt, I get the following results:

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调用工作,直到我设置传感器格式,我们脱轨。

Notice that a few of the DLL calls work, it isn't until I get to setting the sensor format that we go off the rails.

通过检查我正在调用的DLL附带的文档,我看到Windows错误解码为缓冲区的wSize是小的。 (原文如此)。我不知道这是相关的。如果重要,请这里是API文档

By inspecting the documentation that came with the DLL I'm calling, I see the Windows Error decodes to "The wSize of a buffer is to small." (sic). I'm not sure that's relevant. Just in case it matters, here's the API documentation.

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

When I see "works in IDLE, fails at prompt", I assume there must be some environment variable set differently. What should I check?

编辑:

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

I added sys.path and os.getcwd() to the test code.

编辑:

不知道这是否重要,但加载的DLL(SC2_Cam.dll )在当前工作目录中。另外在这个目录是另一个DLL(sc2_cl_me4.dll),我相信是由SC2_Cam.dll加载的。如果我从此目录中删除sc2_cl_me4.dll,则不能对SC2_Cam.dll进行调用,包括PCO_OpenCamera。

Not sure if this matters, but the DLL I load (SC2_Cam.dll) is in the current working directory. Also in this directory is another DLL (sc2_cl_me4.dll), which I believe is loaded by SC2_Cam.dll. If I remove sc2_cl_me4.dll from this directory, none of the calls to SC2_Cam.dll work, including PCO_OpenCamera.

编辑:

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

The code above also works if I type it into the 'vanilla' interactive python interpreter. I don't need IDLE or ipython to make it work. Only calling 'python.exe test.py' fails.

推荐答案

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

When you interface with a C program, you get all the difficulties of C. Any error you make can cause buffer overflows, stack overflows, segmentation violations, etc. If the program, because of an error, writes to a random memory location, its behavior will not be the same in all circumstances. On your machine, it seems to work in interactive mode, but crashes when run from the window command prompt. But on another operating system, or on another machine, or even in the same machine in another day, it could behave differently. Its behavior is not deterministic.

鉴于此,我们来看下面的一行:

Given that, let's look at the following line:

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

根据API文档,在上述调用中, PCO_OpenCamera 函数不仅返回 camera_handle 中的值;它也使用 camera_handle 作为输入值。但是,您离开 camera_value 未初始化。我明白你应该在通话前把它设置为零。另一个问题是 PCO_OpenCamera 返回应该检查的值。如果有问题,但程序继续,如果没有,它将继续为 camera_handle 使用随机值。因此,程序中的一个错误似乎是前一行(保存打印)应该是

According to the API documentation, in the above call, the PCO_OpenCamera function does not just return a value in camera_handle; it also uses camera_handle as an input value. However, you leave camera_value uninitialized. I understand that you should set it to zero before the call. Another problem is that PCO_OpenCamera returns a value which should be checked. If there is a problem but the program continues as if there wasn't, it will continue to use a random value for the camera_handle. So one error in the program seems to be that the preceding line (save the print) should be

camera_handle = ctypes.c_ulong(0)

另一个是 PCO_OpenCamera的返回值未选中。 (我不知道剩下的是否可以,我没有仔细检查过。)

and another is that the return value of PCO_OpenCamera isn't checked. (I don't know if the rest is OK, I haven't examined carefully past that.)

另外,是 c_ulong Windows HANDLE 类型的正确类型?我不知道,可能没关系。即使 c_ulong 大于 HANDLE ,仍然可能确定。但可能还不够你必须确定你知道你在做什么。

Also, is c_ulong the proper type for the Windows HANDLE type? I don't know, and it may be ok. Even if c_ulong is larger than HANDLE, it's still probably OK. But probably is not enough; you must be certain that you know what you're doing.

这篇关于程序在IDLE中工作,但在命令行失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆