As above and how to use them.
Are them Microsoft specific features?
Thanks in advance.
Printable View
As above and how to use them.
Are them Microsoft specific features?
Thanks in advance.
Callback functions are an old concept. They are functions that are not called by the author himself but by another function, for whatever purpose. This is realized via function pointers (pointers that don't contain the address of data, but rather of code).
Callback functions can be used for many thinks: enumerations (since it is complicated to return arrays, these functions are called once for each element of a list), to handle specific computations (there are array sort functions that call a callback to compare two entries of the array), or to handle messages (WNDPROC).
If you have the need, you can do that yourself. You first need to declare a function pointer type:
Notice the bracket around the asterisk and the name - they are important!Code:typedef int (*MYFUNCPTR)(int, int);
// declare a pointer:
MYFUNCPTR ptr;
Then you write a function that takes such a pointer as an argument:
Then you write a function you want to supply:Code:void arraysort(int* ar, int arsize, MYFUNCPTR pfnComp)
{
...
// call the function
k = pfnComp(i, j);
...
}
And finally call the function:Code:int MyFunc(int i, int j)
{
return i*j;
}
No brackets after the function name - you want the address, not the return value.Code:arraysort(ar, ARRAY_SIZE, MyFunc);
The CALLBACK in windows is just an alias for __stdcall, which is a calling convention. You're not concerned with it unless you write in assembly. Just remeber never to mix calling conventions: there are __cdecl, __stdcall and __thiscall (C++ member functions).
There is also __fastcall.
Z.
Wow, CornedBee, you really took time to answer my question.
Thanks, I really appreciated that.
CornedBee, I got one more question. Where is the CALLBACK keyword in your code?
Let me guess the answer.
Every function is stdcall which is an alias for CALLBACK.
I don't use __stdcall.
You can use either __cdecl or __stdcall or __fastcall (right zaei, but this is very similar to __stdcall) for callback functions, I don't know why MS uses __stdcall. I think it is just the standard calling convention for functions in a DLL. WINAPI and APIENTRY (used by most functions in the API including WinMain) is also an alias for __stdcall, and CALLBACK is just used to tell you that this is supposed to be a callback function. (Unlike Win16 where there was some difference, although I don't know which).
Functions without any of those keywords are __cdecl by default, but you can change this in the project settings. But since MS already defined CALLBACK as __stdcall there is no way for you to use __cdecl functions as windows callback - your own callbacks may be __cdecl. See the function pointers:
Code:typedef void (__stdcall *MYSTDCALLFUNCTION)(int);
typedef void (__cdecl *MYCDECLFUNCTION)(int);
void __stdcall Func(int i)
{
printf("%d", i);
}
MYSTDCALLFUNCTION ptr1 = Func; // OK!
MYCDECLFUNCTION ptr2 = Func; // ERROR!
__stdcall makes it slightly easier to clean up I think, since IIRC with this the caller is responsible for removing the parameters from the stack afterwards (i.e. when the function has returned).
__fastcall tries to pass parameters in registers and I don't think it's used much (something like this is of more use on a pure RISC machine where most instructions are register-to-register).
Another stupid question,
How to disable _fastcall in VC, I need to use inline assembly functions in near future. Specifically classes becos I do not know how member functions in classes are called.
Let me guess the answer,
By default, calling conventions are not _fastcall.
You guessed right. By default, calling convention is __cdecl. I don't know if the compiler ever optimizes __stdcall to __fastcall (it has advantages), but it surely won't do it with __cdecl.
parksie: another reason stdcall is used in dlls is that other languages seem to work better with it (specifically: pascal, VB).
Exactly - it's easier to clean up :) (the stack is in the same state, or *should* be ;))
The compiler won't change the calling convention you've set, since it changes how it's called (I think you can use __cdecl [the C calling convention, so the default] in DLLs as well, but I'd have to check).
BTW: A function is a pointer, it's just that what it points at is executable code...following on from this, you can actually do your own dynamic linking by allocating a block of memory, filling it with the instructions, then casting it to a function pointer. Bonzer! :cool: