Program works in IDLE, but fails at the command line

落花浮王杯 提交于 2019-12-14 00:50:54

问题


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]

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
>>> 

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>

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.

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.

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

EDIT:

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

EDIT:

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.

EDIT:

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.


回答1:


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)

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)

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.)

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.




回答2:


Do you have more than one version of python installed on your system? Perhaps you are using a different version when you run interactively and when you run it from a file.




回答3:


The error you're getting leads me to believe that the 16 bit integer you're using to store the wSensor variable is too small. I looked at their API, which just specifies it as type WORD, which historically by Microsoft standards should be 16 bits, but since there is a lot of ambiguity around how big a word is, try upping the value to 32 or 64 bits.

As to why this would cause different behavior in different environments, are you using a 64-bit OS? Do you have a different version of python installed?



来源:https://stackoverflow.com/questions/10525304/program-works-in-idle-but-fails-at-the-command-line

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!