Skip to main content
gamedev.net
🔒 Locked

callback?

Started by andromeda Jun 12, 2002 at 10:28 PM 6 replies 400+ views
Original Post
andromeda
andromeda
I''m just starting to learn DirectX and Windows programming, and I''ve come across something that I hadn''t run into before in any of my C++ books. I know this is a newbie question, but what is a callback function? Like in LRESULT CALLBACK WindowProc(etc, etc,) From what I can gather, it''s some sort of error handling macro...am I right? Any help would be greatly appreciated. Dodge this.
IndirectX
IndirectX
A callback function is basically the one that is called by the operating system.

You can call a function yourself by using f(1, 2, 3); syntax. When Windows needs to call your function, it does so in the exact same way, except you need to provide it with a function pointer which it will call. Your function, pointer to which you give to windows, and which is called by Windows, not by your code directly, is called a callback function.

Imagine a scenario like this: you ask Windows to enumerate all video modes. You can do it in two ways: 1) provide Windows with an array of DEVICE_MODE structures that it will fill with appropriate information, or 2) provide Windows with a function with a prototype like so:

void CALLBACK MyCallback(DEVICE_MODE *mode);

that Windows will call for each mode it finds. Both ways are used by Windows in different circumstances.

The CALLBACK is #defined as __stdcall, it''s the standard Windows calling convention. You must always define callbacks that you feed to Windows with CALLBACK, otherwise you''ll get weird crashes and stack corruptions.
---visit #directxdev on afternet <- not just for directx, despite the name
Fruny
Fruny
A callback function is a function that is meant to be used as a parameter to a system call, which will then ''call back'' that function when some condition holds.

e.g. You create a button, and pass to the create_button function the function you want called when the button is pressed.

Here''s for the concept. In Win32 programming, CALLBACK is a macro that specifies the way the callback function''s parameters are supposed to be passed, so that it matches the way window''s system functions will call them.

Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Coincoin
Coincoin
Im giving you a different answer, maybe it will help to have different point of view.

Callback are usually used for events and enumeration. In your case, WindowProc, this is an event callback. That is, Windows operating system will call this function each time it needs to send a message to your application (such as, mouse clicked, mouse moved, keyboard key pressed, a windows as moved).

Basically what you need to do is fill this function with whatever processing you need to do for these events and then pass that function pointer to windows. This is the only way to program an application under windows GUI (that includes DirectX and OpenGL) without using a wrapper such as GLU or MFC. I know it may seem akward at first look but you will get used to it.
IndirectX
IndirectX
quote:
Original post by Coincoin
This is the only way to program an application under windows GUI (that includes DirectX and OpenGL) without using a wrapper such as GLU or MFC.

I'm pretty sure that you meant GLUT, and AFAIK both GLUT and MFC do use callbacks in the sense that some foreign code (GLUT/MFC in this case) calls your functions. I found some 'linear-game-programing-for-Windows' library a long time ago which supposedly allowed you to write DOS-style linear programs under Windows, but even that library required the client to run a (modified) message loop.

[edited by - IndirectX on June 12, 2002 12:03:57 AM]
---visit #directxdev on afternet <- not just for directx, despite the name
andromeda
andromeda
Thanks for the prompt replies everybody. I believe I understand it now, all the explanations cleared it up well. I think I''m going to like GameDev...



Dodge this.
bravescharm
bravescharm
hello everyone,
I know this is kind of off the subject but i''m having a major problem with a callback functiom. Here is what i''m trying to do:

Ok, let me give you a little more detail. I have a COM object i''ve developed. It uses a library from a third party that allows me to connect to their server. I have a Interface method called Connect which creates an instance of the third party object. This object requires a callback function in it''s constructor, which allows you to recieve messages about the connection to the server. Ok, after creating and instance of this object and passing it my callback function, I call a method on this object called Login

HRESULT MyCOMObject::Connect(user, pass)
{
ThirdPartyObject = new TheObject(MyCallBackFunction);
ThirdPartyObject->Login(user, pass);
return S_OK;
}

Now, when the server has validated my username and pass, it sends me a message through my callback function saying it has connected. It also sends me a error if it was not able to connect to the server. Now, I don''t want to leave my interface method Connect until I have either established a connection with the server or a error has happened, so Connect can return a status code to the client, either saying it connected or didn''t connect. The problem i''m having is the callback function is on the same thread as the callback function. What I am needing to do is somehow not return from Connect until I either i have established a connection or the server send me a error message, which the callback function will recieve. Does anyone know how to sleep inside a function/method and still allow a callback function to recieve messages. I have tried creating two events, one event that gets signaled when a error happened and another event when I was able to established a connection with the server. Then I created a new thread and have that new thread create an instance of the third party object and then call login. After calling login, I call WaitForMulptileObjects, waiting for either of my events to become signaled, because when they''re signaled, then I know my callback function has recieved an event, and depending on which one is signaled, I know if a error happened or I established a connection. The problem with this method is my callback function never gets called because when I call WaitForMulptileObjects, the thread sleeps and the callback never gets called. So i''m having trouble figuring out how to stay in my interface method Connect until I recieve a message by my callback function. if anyone can help, please help because i''m havint trouble thinking of a way. I''ve also wrote a post on this, at

http://www.gamedev.net/community/forums/topic.asp?topic_id=99289



Thanks everyone. Michael
smart_idiot
smart_idiot
I think you're supposed to write '&MyCallBackFunction', although oddly it doesn't seem to matter.

You can mess around with pointers to functions, too if you want. Why let the OS have all the fun?

      
void (*FunctionPointer)() = &FooBar
FunctionPointer(); // invokes 'FooBar'


...

void (*Functions[])(void) = {&Func1, &Func2, &Func3};
Function[1](); // invokes 'Func2'


...

void InvokeMyFunction(void(*ptr)(void))
{
if(ptr)
ptr(); // invokes the function passed if it isn't NULL.

}

...

typedef void(*)(void) FuncPtr;
FuncPtr pointer = &FooBar
pointer(); // invokes 'FooBar'.



At least I think that's how it works. I could be wrong.

It kind of messes up my coding style, using variables as functions, and functions as variables.

[edited by - smart_idiot on June 13, 2002 12:36:15 PM]
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.