【问题标题】:Crash when calling overriden method from glfw callback从 glfw 回调调用覆盖方法时崩溃
【发布时间】:2013-12-27 06:25:36
【问题描述】:

我目前正在开发一个使用 OpenGL 和 GLFW 的跨平台 2D 渲染引擎。我有一个名为 GameWindow 的基窗口类,以及一个继承 GameWindow 的名为 Game 的类。 Game 重写了基类中的一些虚拟方法,以便 GameWindow 可以处理帧限制等。在 GameWindow 的构造函数中,我使用 glfwSetWindowSizeCallback 指定在调整窗口大小时要运行的方法。该方法然后调用 GameWindow 的虚拟 on_resize 方法,该方法会触发 Game 中的覆盖方法。从 GameWindow 中调用任何虚拟方法具有调用 Game 中适当方法的预期效果。但是,如果从 GameWindow 中的窗口调整大小回调调用虚拟方法,应用程序将崩溃。我通过存储 GameWindow 的静态实例并从回调中调用它的 on_resize 方法来解决这个问题。但是,我宁愿不必这样做。这个问题有更好的解决方法吗?提前致谢。

~迈克尔·K。

class GameWindow : Object {
    GLFWwindow* win;
    ...
    public GameWindow(...) {
        ...
        glfwSetWindowSizeCallback(win, (GLFWwindowsizefun)window_size_callback);
    }

    public void run(...) {
        ...
        on_render(renderElapsed);  // This works fine.
        ...
    }

    public virtual void on_resize(int width, int height) {}

    public void window_size_callback(GLFWwindow* window, int width, int height) {
        ...
        on_resize(width, height);  // This causes a crash.
    }
}

class Game : GameWindow {
    ...
    public override void on_render(double time) { ... }

    public override void on_resize(int width, int height) { ... }
}

【问题讨论】:

    标签: vala glfw


    【解决方案1】:

    GLFWwindowsizefun 不接受目标/上下文,因此 Vala 无法将当前的 GameWindow 实例传递给回调。这实际上意味着this 在回调中为空,因此调用on_resize 失败。你的演员隐藏了 Vala 编译器的错误。

    你应该:

    1. window_size_callback 设为静态方法。
    2. 创建某种查找表以在全局变量中从GLFWwindow 中查找GameWindow。 (您可能希望 GameWindow 在查找表中不被拥有,并让 GameWindow 析构函数从查找表中删除。
    3. 在回调中,查找右边的GameWindow并在其上调用on_resize方法。

    【讨论】:

    • 我最终将回调更改为静态并在 GameWindow 的静态实例上调用 on_resize。我希望有一种方法可以避免这种情况,但是哦,好吧。谢谢你的帮助:)
    • 遗憾的是没有。如果底层的 C API 没有很好的方法来传递数据,那么在 Vala 中没有什么可以解决这个问题。
    【解决方案2】:

    就像一个(非常延迟的)更新一样,我又开始搞乱 GLFW,发现它实际上有一种处理这种事情的方法:glfwSetUserPointer 和 glfwGetUserPointer。我最终编辑了我的代码以存储指向调用 GameWindow 实例的指针。在回调方法中,我只是简单地使用 glfwGetUserPointer 来获取所说的指针,并将其转换为 GameWindow 类型。然后我可以像往常一样使用该实例。

    编辑:虽然 apmasell 的回答是正确的,但它主要是针对不允许用户指针之类的库的解决方案。

    【讨论】:

      猜你喜欢
      • 2019-01-02
      • 2015-01-26
      • 1970-01-01
      • 2011-12-13
      • 1970-01-01
      • 2015-08-26
      • 1970-01-01
      • 1970-01-01
      • 2012-05-01
      相关资源
      最近更新 更多