Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在模块级运行与在函数范围内运行时,是什么导致此代码产生不同的结果?_Python_Windows_Winapi_Ctypes_User32 - Fatal编程技术网

Python 在模块级运行与在函数范围内运行时,是什么导致此代码产生不同的结果?

Python 在模块级运行与在函数范围内运行时,是什么导致此代码产生不同的结果?,python,windows,winapi,ctypes,user32,Python,Windows,Winapi,Ctypes,User32,我试图通过Windows API枚举可用的显示监视器。然而,我有一些奇怪的行为,我无法理解。也就是说,函数正确运行,但仅当它不在函数内部时 如果我将其放置在模块级别,如下所示: 模块代码 一切正常。它为我连接的两台显示器打印句柄和矩形 输出: 所以,完全相同的代码,除了现在在函数内部 输出 调用结果:65537无0 0 它没有吐出所有连接的监视器和一个成功代码,而是只吐出一个监视器和一个0,这意味着函数失败 有人知道这是什么原因吗?我被难住了 使用函数时,enum\u回调在enum\u mon

我试图通过Windows API枚举可用的显示监视器。然而,我有一些奇怪的行为,我无法理解。也就是说,函数正确运行,但仅当它不在函数内部时

如果我将其放置在模块级别,如下所示:

模块代码 一切正常。它为我连接的两台显示器打印
句柄
矩形

输出: 所以,完全相同的代码,除了现在在函数内部

输出
调用结果:65537无0
0
它没有吐出所有连接的监视器和一个成功代码,而是只吐出一个监视器和一个0,这意味着函数失败


有人知道这是什么原因吗?我被难住了

使用函数时,
enum\u回调
enum\u mons
的Python帧被垃圾收集时被释放。因此,当Windows试图为每个监视器调用它时,它是否仍然存在是一场竞赛。全局定义回调——或者使用类

您的回调也应该返回True以继续枚举

import ctypes
from ctypes import wintypes 

LPRECT = ctypes.POINTER(wintypes.RECT)

# Callback Factory
MonitorEnumProc = ctypes.WINFUNCTYPE(
    ctypes.c_bool, 
    wintypes.HMONITOR,
    wintypes.HDC,
    LPRECT,
    wintypes.LPARAM)

ctypes.windll.user32.EnumDisplayMonitors.restype = wintypes.BOOL
ctypes.windll.user32.EnumDisplayMonitors.argtypes = [
    wintypes.HDC,
    LPRECT,
    MonitorEnumProc,
    wintypes.LPARAM]

def _monitorEnumProc(hMonitor, hdcMonitor, lprcMonitor, dwData):
    print 'call result:', hMonitor, hdcMonitor, lprcMonitor, dwData
    print lprcMonitor[0].right, lprcMonitor[0].bottom
    return True # continue enumeration

# Make the callback function
enum_callback = MonitorEnumProc(_monitorEnumProc)

def enum_mons():   
    '''Enumerate the display monitors.'''
    return ctypes.windll.user32.EnumDisplayMonitors(
        None, 
        None,
        enum_callback,
        0)

if __name__ == '__main__':
    print 'return code: %d' % enum_mons()

这不是完全相同的代码。其中一个有一个
打印
,另一个没有,还有一个奇怪的列表摆在那里,什么都不做。@user2357112whoop!我以为我把那些都拿走了。现在修好了。代码相同。请再次运行这两个版本,以确保获得发布的输出。如果与您发布的输出(包括格式)有任何不同,请更新问题。当您这样做时,许多bug会神秘地消失。@user2357112更新了问题代码。以同样的结果在我这边运行。代码是复制/粘贴的,其中一个是函数。文本
“返回代码:”
不会出现在您显示的任何输出中。真奇怪。
>>> call result: 65537 None <__main__.LP_RECT object at 0x02250EE0> 0
>>> call result: 65539 None <__main__.LP_RECT object at 0x02250EE0> 0
[Finished in 0.1s]
def _monitorEnumProc(hMonitor, hdcMonitor, lprcMonitor, dwData):
    print 'call result:', hMonitor, hdcMonitor, lprcMonitor, dwData

def enum_mons():
    # Callback Factory
    MonitorEnumProc = WINFUNCTYPE(
        ctypes.c_bool, 
        ctypes.wintypes.HMONITOR,
        ctypes.wintypes.HDC,
        ctypes.POINTER(RECT),
        ctypes.wintypes.LPARAM
    )

    # Make the callback function
    enum_callback = MonitorEnumProc(_monitorEnumProc)

    # Enumerate the windows
    print 'return code: %d' % windll.user32.EnumDisplayMonitors(
        None, 
        None,
        enum_callback,
        0
        )

if __name__ == '__main__':
    enum_mons()
call result: 65537 None <__main__.LP_RECT object at 0x02250E90> 0
0
import ctypes
from ctypes import wintypes 

LPRECT = ctypes.POINTER(wintypes.RECT)

# Callback Factory
MonitorEnumProc = ctypes.WINFUNCTYPE(
    ctypes.c_bool, 
    wintypes.HMONITOR,
    wintypes.HDC,
    LPRECT,
    wintypes.LPARAM)

ctypes.windll.user32.EnumDisplayMonitors.restype = wintypes.BOOL
ctypes.windll.user32.EnumDisplayMonitors.argtypes = [
    wintypes.HDC,
    LPRECT,
    MonitorEnumProc,
    wintypes.LPARAM]

def _monitorEnumProc(hMonitor, hdcMonitor, lprcMonitor, dwData):
    print 'call result:', hMonitor, hdcMonitor, lprcMonitor, dwData
    print lprcMonitor[0].right, lprcMonitor[0].bottom
    return True # continue enumeration

# Make the callback function
enum_callback = MonitorEnumProc(_monitorEnumProc)

def enum_mons():   
    '''Enumerate the display monitors.'''
    return ctypes.windll.user32.EnumDisplayMonitors(
        None, 
        None,
        enum_callback,
        0)

if __name__ == '__main__':
    print 'return code: %d' % enum_mons()