问题
I have an class with instance functions (or methods?). From within an instance, I try to pass pointers to those functions to a library. The library expects static functions.
When I pass my pointers to the callback functions, the compiler complains that my functions are not static. I tried to put make them static, but if I do so, then I can't access the instance fields from within the functions.
How could I go around this?
Similar question is : Using a C++ class member function as a C callback function where they suggest to put the method static. However I can't do that, or I don't see how I could.
Code
GlutController::GlutController (int argc, char **argv) {
// stuff ..
// Register callbacks
glutSpecialFunc( OnSpecialKeys ); // Error, need static functions
glutReshapeFunc( OnChangeSize ); // Error...
glutDisplayFunc( OnRenderScene ); // Error...
// stuff ..
}
GlutController::~GlutController() {
}
void GlutController::OnChangeSize(int aNewWidth, int aNewHeight){
glViewport(0,0,aNewWidth, aNewHeight);
mViewFrustrum.SetPerspective( APP_CAMERA_FOV, // If this function is
float( aNewWidth ) / float( aNewHeight ), // static, this won't
APP_CAMERA_NEAR, // work
APP_CAMERA_FAR );
mProjectionMatrixStack.LoadMatrix( // Same here
mViewFrustrum.GetProjectionMatrix() );
mTransformPipeline.SetMatrixStacks(mModelViewMatrixStack, // Same here
mProjectionMatrixStack);
}
void GlutController::OnRenderScene(void){
mGeometryContainer.draw(); // Won't work if static
}
void GlutController::OnSpecialKeys(int key, int x, int y){
mGeometryContainer.updateKeys(key); // Won't work if static
}
Disclaimer : I just begun C++. I read all of Accelerated C++ and this is my first project to try out the language. My background is in Java.
回答1:
What you are trying to do is not possible. This is glut
's fault actually.
The thing is this:
glut
wants to call a function, without giving it data,- You want your function to use some data,
which are conflicting needs. I believe glut
decided you can safely use global variables.
So, one solution is to use static functions, with static data. Or a better solution would be to switch to SDL.
回答2:
In short, you can't. C++ member functions are actually 'linked' to the instance of the object. On the lower level, they have one extra parameter, which is actually the pointer to the instance of this object.
So, you have to use static function, and, since glut wouldn't let you to pass a parameter which would identify the current instance, you will have to come up with some workaround. The simplest workaround would be to use static members. If your GlutController is singleton (and I think it is), you'll be fine.
回答3:
It is possible and apparently safe to use a file scoped static variable pointing to your GlutInstance (static function + static data, like mentioned in another answer).
static GlutController* s_this;
static void s_OnChangeSize(int w, int h) { s_this->OnChangeSize(w, h); }
GlutController::GlutController (int argc, char **argv) {
s_this = this;
glutSpecialFunc(s_OnSpecialKeys);
}
GlutController::~GlutController() { s_this= 0; }
void GlutController::OnChangeSize(int w, int h) { /* non-static stuff */ }
s_this
is only visible in the local file, e.g. not visible to any code that invokes the GlutController constructor from another file.
回答4:
you should have a static method
and an instance
(possibly static) to call a member function of instance
from static
function
Something like this:
//static method
void MyClass::myCallback()
{
static MyClass instance; //or you can store your in instance in some Singleton, or
//possibly create a temporary
instance.nonStaticMethod();
}
来源:https://stackoverflow.com/questions/11792664/to-pass-a-pointer-to-a-member-function