Ошибка возникает только при компиляции с -O3 - PullRequest
4 голосов
/ 07 декабря 2011

При создании инструментария OpenGL с использованием GLFW и Cython я наткнулся на очень, очень странную проблему.Я создал следующий файл 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 , он не вылетает и работает как надо! Я полностью сбит с толку.Я проверил код C, который выводит Cython, и он выглядит нормально._mouse_scroll_callback_handler имеет тип void (*)(int), и указатель на него красиво передается в glfw.

Другие странности:

  • Это происходит только с glfwSetMouseWheelCallback (или припо крайней мере для меня), а не с glwSetMousePosCallback, например.
  • Если я передам NULL на glfwSetMouseWheelCallback, проблем не будет.
  • Даже при сбое TEST LOCATION ONE все равно будет напечатан, но TEST LOCATION TWO не работает.
  • Это также работает, если я скомпилирую с -O3 -pg

Что может быть причиной этого и что будет правильнымисправить (без необходимости компилировать в -O0)?


Другие мелочи:

Я использую 64-битную Windows 7, GLFW 2.7.2, Cython 0.15.1, GCC 4.6.1 под MinGW и CPython 2.7.2.

1 Ответ

2 голосов
/ 19 декабря 2011

Я наконец нашел решение. Проблема заключалась в том, что я не добавил __stdcall в Cython к функциям обратного вызова, и при этом я не знал, что это поддерживает это.

...