我尝试使用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
求各位帮忙看一下,到底错在哪儿了呀??!!