0

I'm attempting to set my glfw error and key callbacks to a function in class Game. When doing this, I get undefined references to the callback functions.

Here's what the relevant parts of the class looks like:

namespace TGE
{
    class Game
    {
        public:
            void init()
            {
                glfwSetErrorCallback(error_callback)

                if(!glfwInit())
                    exit(EXIT_FAILURE);

                window = glfwCreateWindow(800, 600, "Test", NULL, NULL);

                if(!window)
                {
                    glfwTerminate();
                    exit(EXIT_FAILURE);
                }

                glfwMakeContextCurrent(window);
                glfwSetKeyCallback(window, key_callback);

                start();
            }

            void start()
            {
                // Main loop stuff
            }

            static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
            {
                if(action == GLFW_PRESS)
                {
                    switch(key)
                    {
                        case GLFW_KEY_ESCAPE:
                            glfwSetWindowShouldCLose(window, GL_TRUE);
                            break;
                    }
                }
            }

            static void error_callback(int error, const char* description)
            {
                fputs(description, stderr);
            }

        protected:
            GLFWwindow* window;
    }
}

When I try to compile I get

In function `TGE::Game::init()`:
undefined reference to `TGE::Game::error_callback(int, char const*)`
undefined reference to `TGE::Game::key_callback(GLFWwindow*, int, int, int, int)`

I have a feeling it may be because of the namespace, but I'm not sure how to get around that if it is.

EDIT: Moving everything out of the namespace results in the same error.

4

2 回答 2

-1

我认为这是因为您对error_callback(...)and的定义key_callback(...)出现在init()函数之后,两者都被使用。

编辑: 忽略这个,这不是原因,因为它是一个链接器错误(见下面的评论)

于 2013-10-31T14:19:17.470 回答
-1

我怀疑这里发生的事情是您在类声明中定义了静态成员函数,这使得它们隐式地成为inline. 由于一些编译器错误(或者甚至可能是标准指定的行为?),编译器没有实例化这些函数的非内联版本,这些函数实际上有一个地址和一个全局符号。

无论这是否正确,仅通过指针用作回调的内联函数无论如何都是无稽之谈。所以为什么它不起作用是没有实际意义的。通过指针进行的函数调用不是内联的。

您应该只在类声明中声明这些函数,然后在某个地方实现它们。

// inside the class decl:
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);

和:

// inside some implementation file

#include "the_above_header.h"

// ...
void TGE::Game::key_callback(GLFWwindow*, int, int, int, int)
{
   // ...
}

确保此文件已编译并链接。

但是,该命令使用 g++ 4.6.3 为我编译和链接以下测试程序。

#include <stdlib.h>
#include <stdio.h>

// Wrapping the class in a namespace makes no difference, by the way.
class test {
  int x[42];
public:
  test()
  {
    qsort(x, 42, sizeof x[0], compare);
  }
  static inline int compare(const void *, const void *)
  {
    return 0;
  }
};

int main(void)
{
  test t;
  return 0; 
}
于 2013-10-31T14:45:43.700 回答