8

我正在使用 MSVC++ 和 freeglut 来使用 openGL。现在,我有一个名为 的类Camera,它非常简单,但它也包含用于重塑我的窗口的功能。

我的问题是:如何glutReshapeFunc(void (*callback)(int,int))在相机中设置我的功能?

由于编译器错误,我有以下代码不起作用:

int main(int argc, char **argv)
{
    Camera *camera = new Camera();
    glutReshapeFunc(camera->ReshapeCamera);
}

我的 Camera 类在Camera.h中看起来像这样:

class Camera
{
public:
    Camera(void);
    ~Camera(void);
    void ReshapeCamera(int width, int height);
};

也许这只是一个更一般的回调问题,但我在互联网上发现的唯一一件事就是围绕回调创建一些包装类。但看起来这应该不是那么难。提前致谢。

4

4 回答 4

10

没有干净的方法可以做到这一点。C 不知道对象,因此指向成员的指针不起作用。C 不做模板,所以函子不起作用。API 甚至不允许您向void *userData回调传递任意值,因此您也不能以这种方式传递对象。

因此,确实,您必须创建一个不是成员函数的包装函数,并且您必须Camera通过静态和/或全局变量以某种方式授予它访问对象实例的权限。

如果可以有多个对象侦听此事件,您可以创建一个允许您注册任意侦听器的单例类。

于 2011-02-15T19:09:53.273 回答
2

不能直接连接。ReshapeCamera 是一个成员函数,它需要一个相机实例才能运行。过剩回调是一个 C 函数,它没有相机实例来调用您的方法。您需要创建一个调用相机重塑方法的函数。

于 2011-02-15T19:08:39.127 回答
2

它与“C vs C++”无关。您只需要了解成员函数调用的含义以及它编译的基本内容。

myObject.memberFunction(); // This is what the programmer sees.
memberFunction(&myObject); // This is what the compiler sees.

成员函数是对简单地将对象作为第一个参数的函数的精美描述。它只是在实际参数列表中不可见。

void MyClass::memberFunction() // This is the declaration the programmer sees.
void memberFunction(MyClass* this) // This is what the compiler sees.

从那里开始,C++ 添加了特殊的语义,使其易于以面向对象的方式工作。因此,即使您的对象具有格式 void(int, int) 的成员函数,它实际上具有格式 void(Camera*, int, int),并且与所需的格式不匹配!这就是为什么静态函数成员可以用于此类函数指针的原因。有没有注意到静态成员函数不能访问“this”的成员?这是因为静态成员函数传递表示“this”的对象的实例。

实际上,您可以在纯 C 中模拟许多面向对象的编程。如果您创建一组以结构指针作为第一个参数的函数,您将获得许多相同的优势!

于 2011-02-15T21:22:35.080 回答
0

下面演示如何从 c++ 注册 ac 回调函数,它一般有用,不是特定于 glut。

这是您的客户端 C++ 程序

int main(int argc, char *argv[]) {

std::cout << "launching Camera ..." << std::endl;

Camera * camera = new Camera();

// ------ glut new window boilerplate ------- //

int WindowHandle = 0;
glutInit(&argc, argv);
WindowHandle = glutCreateWindow("hello there");
if(WindowHandle < 1) {
    std::cerr << "ERROR: Could not create a new rendering window" << std::endl;
    exit(EXIT_FAILURE);
}
// ------------------------------------------ //

camera->setup_callback();

glutMainLoop();

return 0;

}

这是Camera.cpp

Camera * ptr_global_instance = NULL;

extern "C" void ReshapeCamera_callback(int width, int height) {
    // c function call which calls your c++ class method
    ptr_global_instance->ReshapeCamera_cb(width, height);
}

void Camera::ReshapeCamera_cb(int width, int height) {
    std::cout << "width " << width << " height " << height << std::endl;
}

void Camera::setup_callback() {
    // c++ method which registers c function callback
    ::ptr_global_instance = this;
    ::glutReshapeFunc(::ReshapeCamera_callback);
}

及其头文件 Camera.h

class Camera {
public:
    void ReshapeCamera_cb(int width, int height);
    void setup_callback();
};

注意 c++ 全局类指针 ptr_global_instance 的使用

于 2013-08-04T20:00:40.647 回答