只有在使用-O3进行编译时才会发生错误

时间:2011-12-07 08:24:10

标签: gcc cython glfw

在使用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。

其他奇怪之处:<​​/ p>

  • 这只发生在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。

1 个答案:

答案 0 :(得分:2)

我终于找到了解决方案。问题是我没有在Cython中将__stdcall添加到回调函数中,也不知道它支持这个。