Static data and static member functions....
Hi,
I'm wrapping up all my Dx code and I've got a problem coding callback functions as member functions.
The prototypes for the callbacks are "static HRESULT .." etc etc, so the member func defined this way will only work with static data.
No matter how I try I cannot hack my way around the static / non-static boundaries! I doubt there anyway I can make these callback functions modify object specific data (as this seems to contradict the whole "static" protocol).
Another problem I have involves the VC++ class wizard. This neatly makes a .h and .cpp file for each new class, but according to the helper files static data and functions have "file scope". So if any member function within class.cpp tries to access a static variable declared in class.h, I get linker errors.
Can anyone help me through this mess?
Please take pity on a poor C programmer, I'm trying really hard but this rehabillitation is sometimes very painful
Cheers
Matt
Edited by - 3dmodelman on January 3, 2001 7:51:17 PM
To make your static members available to other files, add an ''extern'' statement into the header files of the class, and include these in any source files you want to use them in.
Hope this helps.
Starfall
extern int MyClass::MyInt;
Hope this helps.
Starfall
Is it possible that the class that contains these callbacks only has a single instance? If so, you might want to look at a singleton pattern, which will give you only one object of the class that is available anywhere, even within static member functions of that class. Furthermore, your callbacks would be able to manipulate the private data of the object (being member functions).
If not, the problem gets really tricky. If you have multiple instances of class X, and each one gets a specific DX callback, I''m not sure how you would make that work unless the callback allows an optional parameter. Usually, this IS the case specifically for this reason, so look into that.
For example, the win32 function wavOutOpen requires you supply a callback and a 32-bit DWORD to pass to the callback. You would use this DWORD to pass a pointer to your class instance. Then, in your callback function, you would cast that DWORD to a pointer to the class object, and then use that pointer just like "this".
If not, the problem gets really tricky. If you have multiple instances of class X, and each one gets a specific DX callback, I''m not sure how you would make that work unless the callback allows an optional parameter. Usually, this IS the case specifically for this reason, so look into that.
For example, the win32 function wavOutOpen requires you supply a callback and a 32-bit DWORD to pass to the callback. You would use this DWORD to pass a pointer to your class instance. Then, in your callback function, you would cast that DWORD to a pointer to the class object, and then use that pointer just like "this".
Static member functions should be visible to any file that includes the class header... ''static'' on a member function doesn''t mean the same thing as ''static'' on a non-member function.
static for member functions means ''shared among the class members''... ie. a ''normal'' function in that Class''s namespace. So, if you want it to operate on an object, you need to somehow pass details of your intended object to the function. I''m guessing that, since it''s a callback, you can''t alter the parameter list of the function, so maybe something like this would help?
static for member functions means ''shared among the class members''... ie. a ''normal'' function in that Class''s namespace. So, if you want it to operate on an object, you need to somehow pass details of your intended object to the function. I''m guessing that, since it''s a callback, you can''t alter the parameter list of the function, so maybe something like this would help?
class MyClass{static MyClass* callback_this;static HRESULT someCallbackFunction(blah, blah);}// Set this variable to whatever is relevant,// before the callback function gets is calledMyClass::callback_this = NULL;static HRESULT MyClass::someCallbackFunction(blah, blah){ // This function has access to ''callback_this'' if (!callback_this) return FAILED; callback_this->DoSomething(); callback_this->DoSomethingElse(); return whatever;}
Thanks for your input guys
I have it working now, but not they way I''d like it to. The variable I''m trying to access inside the callback is just a pointer to a debug stream class, so I can output messages from within the callback function itself.
I tried using extern in the .cpp file, but that still gave linker errors, so in the end (while experimenting) I declared a global with the same name. Now everything works fine I know the callback is using the same pointer as the rest of the member functions, I just don''t know why. One of them is a "static CDebugLog * " declared in the .h, and one of them is just a global declared in the .cpp.
I like your suggestion kylotan, I''m going to try that next.
Cheers
Matt
I have it working now, but not they way I''d like it to. The variable I''m trying to access inside the callback is just a pointer to a debug stream class, so I can output messages from within the callback function itself.
I tried using extern in the .cpp file, but that still gave linker errors, so in the end (while experimenting) I declared a global with the same name. Now everything works fine I know the callback is using the same pointer as the rest of the member functions, I just don''t know why. One of them is a "static CDebugLog * " declared in the .h, and one of them is just a global declared in the .cpp.
I like your suggestion kylotan, I''m going to try that next.
Cheers
Matt
Ok, it''s working now, but it still seems ugly...
in the .h file;
BUT, the static data certainly does have file scope, so I cannot access it in the .cpp file! To get round that, in the .cpp file;
So it has to be set up as a global variable still. Trying to use "extern" is not allowed on members.
I guess it''ll have to stay like this.
Thanks everyone
Matt
in the .h file;
class CMattsDirect3D
{
static CMattsDirect3D * callback_this;
}
BUT, the static data certainly does have file scope, so I cannot access it in the .cpp file! To get round that, in the .cpp file;
#include..
#include..
CMattsDirect3D * CMattsDirect3D::callback_this;
// member functions start here
So it has to be set up as a global variable still. Trying to use "extern" is not allowed on members.
I guess it''ll have to stay like this.
Thanks everyone
Matt
quote: Original post by 3dModelMan
BUT, the static data certainly does have file scope, so I cannot access it in the .cpp file! To get round that, in the .cpp file;
#include..
#include..
CMattsDirect3D * CMattsDirect3D::callback_this;
// member functions start here
So it has to be set up as a global variable still. Trying to use "extern" is not allowed on members.
I think you are misunderstanding something But that''s probably cos we never explained it properly
Static member variables do not have file scope as such. They do not really have any scope in the way that a C-style variable does. In fact, they are little more than a glorified global anyway, one that just happens to be inside a class''s namespace.
Since they are shared among the class, and not part of any individual object, the storage needs to be allocated and therefore they need to be declared somewhere. Traditionally, this is in the classes accompanying .cpp file, and is done exactly the way you did it. So, what you did was not some sort of workaround, as you seemed to think... it''s how static member variables have to be declared.
However, this doesn''t give that static member variable file scope! It doesn''t matter which file you put that declaration in, so long as the linker can find it. The scope of that member variable is the scope of its owning class... so to use it, you simply need to have access to that class (ie. include "CMattsDirect3D.h" or whatever.) You''d then use it like so:
// From outside of the class, use scope resolution
void OtherFunction()
{
CMattsDirect3D::callback_this = NULL;
}
// From inside the class, you don''t need it
void CMattsDirect3D::MemberOrStaticFunction()
{
callback_this = NULL;
}
The callback_this variable will be visible anywhere that the CMattsDirect3D class is visible.
That make sense?
Thanks again Kylotan - the penny has finally droppped
I was expecting some kind of redefinition error the way it was done.
Thanks for your patience, I''m working through Lafore''s "C++ Interactive Course" so I''m not doing this completely blind folded but I guess I''ll come across a few cases like this when it actually comes to implementing it for the first time.
Cheers
Matt
I was expecting some kind of redefinition error the way it was done.
Thanks for your patience, I''m working through Lafore''s "C++ Interactive Course" so I''m not doing this completely blind folded but I guess I''ll come across a few cases like this when it actually comes to implementing it for the first time.
Cheers
Matt
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement