在使用GLFW和Cython制作OpenGL工具包时,偶然发现了一个非常非常奇怪的问题.我创建了以下文件pxd文件(非常大,所以我对它进行了强化):
https://gist.github.com/1441970
接下来我有这个包装代码(非常简化以显示问题的核心).
pygrafix.window模块:
from pygrafix.c_headers.glfw cimport * # this is the pxd file
glfwInit()
_window = None
cdef void _mouse_scroll_callback_handler(int pos):
if _window._mouse_scroll_callback:
_window._mouse_scroll_callback(_window, pos)
cdef class Window:
cdef public object _mouse_scroll_callback
def __cinit__(self):
global _window
self._mouse_scroll_callback = None
_window = self
def __init__(self, int width = 0, int height = 0):
glfwOpenWindow(width, height, 0, 0, 0, 0, 0, 0, GLFW_WINDOW)
glfwSetMouseWheelCallback(<GLFWmousewheelfun> &_mouse_scroll_callback_handler)
print("TEST LOCATION ONE")
def is_open(self):
return glfwGetWindowParam(GLFW_OPENED)
def flip(self):
glfwSwapBuffers()
def set_mouse_scroll_callback(self, func):
self._mouse_scroll_callback = func
而这个主文件:
from pygrafix import window
window = window.Window(800, 600)
print("TEST LOCATION TWO")
def on_scroll(window, pos):
print(pos)
window.set_mouse_scroll_callback(on_scroll)
while window.is_open():
window.flip()
最后我像这样编译它:
cython.py -o pygrafix/window.cy.c pygrafix/window.pyx
gcc -O3 -shared -DGLFW_DLL -IC:\Python27\include pygrafix/window.cy.c -o pygrafix/window.pyd -LC:\Python27\libs -lpython27 -lgfwldll
但它崩溃了(Windows说程序中有错误).当我注释掉对glfwSetMouseWheelCallback的调用时,它不会崩溃.
奇怪的是,如果我使用-O0进行编译,它不会崩溃并且可以正常工作!我完全被这个困惑了.我检查了cython输出的C代码,看起来没问题.
_mouse_scroll_callback_handler的类型为void(*)(int),指向它的指针很好地传递给glfw.
其他奇怪之处:
>这只发生在glfwSetMouseWheelCallback(或者至少对我来说),而不是像glwSetMousePosCallback那样.
>如果我将NULL传递给glfwSetMouseWheelCallback,则没有问题.
>即使发生了碰撞,TEST LOCATION ONE仍会打印,但TEST LOCATION TWO不会打印.
>如果我用-O3 -pg编译它也有效
可能是什么原因,什么是正确的修复(无需在-O0编译)?
其他琐事:
我在MinGW和CPython 2.7.2下使用Windows 7 64位,GLFW 2.7.2,Cython 0.15.1,GCC 4.6.1.
最佳答案 我终于找到了解决方案.问题是我没有在Cython中将__stdcall添加到回调函数中,也不知道它支持这个.