我正在尝试将我的glfw错误和关键回调设置为类Game中的函数。这样做时,我得到了对回调函数的未定义引用。
以下是该课程的相关部分:
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;
}
}
当我尝试编译时,我得到了
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)`
我有一种感觉,可能是因为名称空间,但我不确定如何解决这个问题。
编辑:将所有内容移出命名空间会导致同样的错误。
答案 0 :(得分:-1)
我认为是因为您对error_callback(...)
和key_callback(...)
的定义是在init()
函数之后,两者都使用了。
修改强> 忽略这一点,这不是原因,因为它是一个链接器错误(见下面的评论)
答案 1 :(得分:-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;
}