Python 中 ctypes 模块报错

我尝试使用ctypes模块做一个对glfw3的封装,在这个过程中,我遇到了一些问题。

glfwSetMonitorCallback这个函数似乎难以封装,它接受一个回调函数作为参数,又返回一个回调函数表示上一次设置的回调函数。而且这个回调函数的类型GLFWmonitorfun中还学要接收一个指针参数GLFWmonitor *monitor

typedef void (* GLFWmonitorfun)(GLFWmonitor* monitor, int event);
// ...
GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun callback);

我在对GLFWmonitorfun的封装如下:

GLFWmonitorfun = CFUNCTYPE(None, POINTER(GLFWmonitor), c_int)

我的思路是,在封装的函数内再加一层函数对指针进行处理:

def glfwSetMonitorCallback(callback):
    def cb(monitor, event):
        if monitor:
            callback(monitor.contents, event)
        else:
            callback(None, event)

    glfw3.glfwSetMonitorCallback.argtypes = [GLFWmonitorfun]
    glfw3.glfwSetMonitorCallback.restype = GLFWmonitorfun

    last_callback = glfw3.glfwSetMonitorCallback(GLFWmonitorfun(cb))

    def last_cb(monitor, event):
        last_callback(byref(monitor), event)

    return last_cb

我的main.py文件内容如下:

from pyglfw3 import *


def cb(monitor, event):
    print(monitor, event)


glfwInit()
m = glfwGetPrimaryMonitor()
glfwSetMonitorCallback(cb)        # 第一次先设置回调
glfwSetMonitorCallback(cb)(m, 0)  # 第二次按理来说应该返回第一次设置的回调

但是不出所料地,报错了:

Traceback (most recent call last):
  File "C:\Users\Lenovo\code\Python\opengl_learning\main.py", line 11, in <module>
    glfwSetMonitorCallback(cb)(m, 0)
  File "C:\Users\Lenovo\code\Python\opengl_learning\pyglfw3.py", line 500, in last_cb
    last_callback(byref(monitor), event)
OSError: exception: access violation reading 0xFFFFFFE1C76012D0

经过调试,我能确保glfwGetPrimaryMonitor函数返回的值无误,是一个完整的GLFWmonitor对象,保险起见,还是把定义写出来吧:

def glfwGetPrimaryMonitor():
    glfw3.glfwGetPrimaryMonitor.restype = POINTER(GLFWmonitor)
    monitor = glfw3.glfwGetPrimaryMonitor()
    if monitor:
        return monitor.contents
    return None

求各位帮忙看一下,到底错在哪儿了呀??!!